Respostas:
Em suma, não. Você não pode conectar automaticamente ou conectar manualmente os campos estáticos no Spring. Você terá que escrever sua própria lógica para fazer isso.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
foi inicializado se acessado estaticamente: NewClass.staticMethodWhichUsesSomething();
pode lançar uma NPE se usado antes da inicialização aplicativo
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
pode ser usado com setters para que você possa ter um setter modificando um campo estático.
Apenas uma sugestão final ... NÃO
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Inicie seu componente autowired no método @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)
?
Você pode conseguir isso usando a notação XML e o MethodInvokingFactoryBean
. Para um exemplo, veja aqui .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Você deve usar a injeção de mola sempre que possível, pois esta é a abordagem recomendada, mas isso nem sempre é possível, pois tenho certeza de que você pode imaginar que nem tudo pode ser retirado do contêiner de mola ou talvez você esteja lidando com sistemas legados.
Nota: o teste também pode ser mais difícil com essa abordagem.
Você pode usar o ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
então
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Queria adicionar às respostas que o campo estático (ou constante) da fiação automática será ignorado, mas também não criará nenhum erro:
@Autowired
private static String staticField = "staticValue";
Isenção de responsabilidade Isso não é de forma alguma padrão e poderia muito bem haver uma maneira melhor de fazer isso. Nenhuma das respostas acima aborda os problemas de conectar um campo estático público.
Eu queria realizar três coisas.
Meu objeto fica assim
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Já marcamos 1 e 2 agora, como evitamos chamadas para o setter, pois não podemos ocultá-lo.
@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;
}
}
Esse aspecto envolve todos os métodos que começam com final e gera um erro se eles forem chamados.
Eu não acho que isso seja particularmente útil, mas se você é ocd e gosta de manter as ervilhas e as cenouras separadas, essa é uma maneira de fazê-lo com segurança.
Importante O Spring não chama seus aspectos quando chama uma função. Tornou isso mais fácil, até que eu trabalhei na lógica antes de descobrir isso.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);