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.
Quando você encontra código antigo fazendo isso, é um anti-padrão. Aperte os olhos, incline a cabeça e encontre uma maneira melhor de resolver o problema. Você ficará feliz por ter feito.
alguma idéia de como posso usar essa abordagem ao inicializar um repositório?
Kryysktos 8/03
3
A desvantagem: Não há nenhuma garantia de que someThingfoi inicializado se acessado estaticamente: NewClass.staticMethodWhichUsesSomething();pode lançar uma NPE se usado antes da inicialização aplicativo
Neeraj
Você pode evitar o aviso de Instance methods should not write to "static" fields (squid:S2696)?
user7294900
@ user7294900: desative este aviso apenas neste caso muito específico.
Izogfif 6/06/19
@izogfif ainda um problema se eu optar por esta solução em casos gerais e classes
user7294900
67
@Autowired pode ser usado com setters para que você possa ter um setter modificando um campo estático.
Hmmm .. meu sentimento sobre por que não é recomendado é, porque a instância estática na classe está além do controle da primavera. Uma vez injetado, o campo estático é a referência para todas as instâncias de objetos da classe correspondente (ao redor). Mas, este comportamento pode ser exatamente o que se espera que aconteça, portanto, pode ser visto como um bug ou um recurso ...
matthaeus
1
Sim, @matthaeus, é exatamente o recurso que eu esperava quando precisava acessar org.springframework.core.env.Environment:@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
user1767316:
@JonLorusso e tudo Porque quando o carregador de classes carrega os valores estáticos, o contexto do Spring ainda não é necessário. Portanto, o carregador de classes não injeta corretamente a classe estática no bean e falha. Resposta fornecida por Andrea T
Jeril Kuruvila
14
Inicie seu componente autowired no método @PostConstruct
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.
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.
Já marcamos 1 e 2 agora, como evitamos chamadas para o setter, pois não podemos ocultá-lo.
@Component@AspectpublicclassFinalAutowiredHelper{@Before("finalMethods()")publicvoid beforeFinal(JoinPoint joinPoint){thrownewFinalAutowiredHelper().newModifySudoFinalError("");}@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")publicvoid finalMethods(){}publicclassModifySudoFinalErrorextendsError{privateString msg;publicModifySudoFinalError(String msg){this.msg = msg;}@OverridepublicString 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.
Embora esse código possa resolver a questão, incluindo uma explicação de como e por que isso resolve o problema realmente ajudaria a melhorar a qualidade da sua postagem e provavelmente resultará em mais votos positivos. Lembre-se de que você está respondendo à pergunta dos leitores no futuro, não apenas à pessoa que está perguntando agora. Por favor edite sua resposta para adicionar explicações e dar uma indicação do que limitações e premissas se aplicam.
bip duplo
Eu acho que essa resposta pode não precisar de nenhuma explicação.
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.
fonte
@AutoWired
fonte
someThing
foi inicializado se acessado estaticamente:NewClass.staticMethodWhichUsesSomething();
pode lançar uma NPE se usado antes da inicialização aplicativoInstance 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
fonte
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Inicie seu componente autowired no método @PostConstruct
fonte
Instance methods should not write to "static" fields (squid:S2696)
?Crie um bean que você possa conectar automaticamente, que inicializará a variável estática como efeito colateral.
fonte
Você pode conseguir isso usando a notação XML e o
MethodInvokingFactoryBean
. Para um exemplo, veja aqui .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.
fonte
Você pode usar o ApplicationContextAware
então
fonte
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:
fonte
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
Já marcamos 1 e 2 agora, como evitamos chamadas para o setter, pois não podemos ocultá-lo.
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.
fonte
fonte