Відповіді:
Словом, ні. Не можна автоматично з'єднувати або вручну проводити статичні поля навесні. Для цього вам доведеться написати власну логіку.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
яка була ініціалізована, якщо матиме доступ до неї статично: NewClass.staticMethodWhichUsesSomething();
може кинути NPE, якщо вона буде використана перед ініціалізацією додатків
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
можна використовувати із сеттерами, щоб у вас міг бути сетер, що змінює статичне поле.
Лише одна остаточна пропозиція ... НЕ
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Запустіть свій автоматичний компонент в методі @PostConstruct
@Component
public class TestClass {
private static AutowiredTypeComponent component;
@Autowired
private AutowiredTypeComponent autowiredComponent;
@PostConstruct
private void init() {
component = this.autowiredComponent;
}
public static void testMethod() {
component.callTestMethod();
}
}
Instance methods should not write to "static" fields (squid:S2696)
?
Ви можете досягти цього, використовуючи позначення XML та MethodInvokingFactoryBean
. Для прикладу дивіться тут .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Ви повинні прагнути використовувати пружинну ін'єкцію, де це можливо, оскільки це рекомендований підхід але це не завжди можливо, оскільки я впевнений, що ви можете уявити, що не все можна витягнути з пружинного контейнера або, можливо, ви маєте справу зі застарілими системами.
Зверніть увагу, тестування також може бути складніше при цьому підході.
Хотіли додати у відповіді, що статичне поле (або постійне) автоматичного проводки буде ігноровано, але також не створить жодної помилки:
@Autowired
private static String staticField = "staticValue";
Ви можете використовувати ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
тоді
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Відмова від відповідальності Це аж ніяк не стандарт, і це може бути найкращим весняним способом зробити це. Жодна з наведених відповідей не стосується питань проводки публічного статичного поля.
Я хотів здійснити три речі.
Мій об’єкт виглядає так
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Ми вже перевірили 1 і 2, як запобігти викликам до сетера, оскільки ми не можемо його приховати.
@Component
@Aspect
public class FinalAutowiredHelper {
@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}
@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}
public class ModifySudoFinalError extends Error {
private String msg;
public ModifySudoFinalError(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return "Attempted modification of a final property: " + msg;
}
}
Цей аспект буде обгортати всі методи, починаючи з остаточного, і призведе до помилки, якщо вони викликаються.
Я не вважаю, що це особливо корисно, але якщо ви неприйнятні і хочете тримати вас горох та моркву, це один із способів зробити це безпечно.
Важливо Spring не називає ваші аспекти, коли він викликає функцію. Це полегшило, до поганого я розробив логіку, перш ніж з'ясувати це.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);