Есть ли способ использовать @Autowired
со статическими полями. Если нет, есть ли другие способы сделать это?
Можете ли вы использовать @Autowired со статическими полями?
Ответ 1
Короче говоря, нет. Вы не можете автообновлять или вручную прокладывать статические поля в Spring. Вы должны будете написать свою собственную логику, чтобы сделать это.
Ответ 2
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
Ответ 3
@Autowired
может использоваться с сеттерами, чтобы у вас мог быть сеттер, изменяющий статическое поле.
Только одно окончательное предложение... НЕ
Ответ 4
Инициируйте свой автопроводной компонент в методе @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();
}
}
Ответ 5
Создайте bean, который вы можете autwire, который инициализирует статическую переменную как побочный эффект.
Ответ 6
Вы можете достичь этого, используя XML-нотацию и MethodInvokingFactoryBean
. Например, посмотрите здесь.
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Вы должны стремиться использовать spring инъекцию, если это возможно, поскольку это рекомендуемый подход, но это не всегда возможно, поскольку я уверен, что вы можете себе представить, что не все можно вытащить из spring или вы, возможно, имеете дело с устаревшими системами.
Примечание: для этого подхода также может быть сложнее провести тестирование.
Ответ 7
Вы можете использовать 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);
Ответ 8
Отказ от ответственности Это ни в коем случае не стандарт, и вполне может быть лучший весенний способ сделать это. Ни один из вышеприведенных ответов не затрагивает вопросы подключения открытого статического поля.
Я хотел сделать три вещи.
- Используйте пружину для "Autowire" (я использую @Value)
- Выставить публичное статическое значение
- Предотвратить изменение
Мой объект выглядит так
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;
}
}
Этот аспект обернет все методы, начинающиеся с final, и выдаст ошибку, если они вызваны.
Я не думаю, что это особенно полезно, но если вы любите держать горох и морковь отдельно, это один из способов сделать это безопасно.
Важно Spring не вызывает ваши аспекты, когда вызывает функцию. Сделал это проще, к сожалению, я разработал логику, прежде чем понять это.
Ответ 9
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);