Tenho @Autowired
serviço que deve ser usado de dentro de um método estático. Sei que isso está errado, mas não posso alterar o design atual, pois isso exigiria muito trabalho, então preciso de um hack simples para isso. Não posso mudar randomMethod()
para não estático e preciso usar este bean autowired. Alguma pista de como fazer isso?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Respostas:
Você pode fazer isso seguindo uma das soluções:
Usando o construtor @Autowired
Essa abordagem construirá o bean exigindo alguns beans como parâmetros do construtor. Dentro do código do construtor, você define o campo estático com o valor obtido como parâmetro para a execução do construtor. Amostra:
Usando @PostConstruct para entregar o valor ao campo estático
A ideia aqui é entregar um bean a um campo estático depois que o bean for configurado na primavera.
fonte
Você deve contornar isso por meio da abordagem de acessador de contexto de aplicativo estático:
Então, você pode acessar as instâncias do bean de maneira estática.
fonte
getBean
antes que o contexto seja inicializado (NPE) ou depois que o contexto com seus beans for destruído. Essa abordagem tem a vantagem de que o acesso ao contexto estático "feio" é incluído em um método / classe.O que você pode fazer é
@Autowired
um método setter e definir um novo campo estático.Quando o bean for processado, o Spring injetará uma
Foo
instância de implementação no campo de instânciafoo
. Em seguida, ele também injetará a mesmaFoo
instância nasetStaticFoo()
lista de argumentos, que será usada para definir o campo estático.Esta é uma solução terrível e falhará se você tentar usar
randomMethod()
antes que o Spring tenha processado uma instância deBoo
.fonte
setStaticFoo()
seja, sem oFoo
parâmetro.É uma merda, mas você pode obter o bean usando a
ApplicationContextAware
interface. Algo como :fonte
Isso se baseia na resposta de @Pavel, para resolver a possibilidade de o contexto Spring não ser inicializado ao acessar a partir do método getBean estático:
A peça importante aqui é o
initContext
método. Isso garante que o contexto sempre será inicializado. Mas, observe queinitContext
será um ponto de discórdia em seu código, pois ele está sincronizado. Se seu aplicativo for muito paralelizado (por exemplo: o back-end de um site de alto tráfego), essa pode não ser uma boa solução para você.fonte
Use AppContext. Certifique-se de criar um bean em seu arquivo de contexto.
fonte