Como injetar dependências em um objeto auto-instanciado no Spring?
Digamos que temos uma aula:
Em seguida, criamos um objeto dessa classe (ou alguma outra estrutura criou a instância dessa classe).
Ainda é possível injetar as dependências? Algo como:
(Acho que o Google Guice tem algo assim)
— Igor Mukhin
Você pode fazer isso usando o autowireBean()método de AutowireCapableBeanFactory. Você o passa como um objeto arbitrário, e o Spring o tratará como algo que ele próprio criou e aplicará os vários bits e partes da fiação automática.
Para se apossar do AutowireCapableBeanFactory, basta autowire que:
Boa resposta (+1). Há também um segundo método, onde pode influenciar a forma como o autowiring acontece: static.springsource.org/spring/docs/3.0.x/javadoc-api/org/...
Mas e se eu tiver dois objetos, e o primeiro autowires em segundo. Como a fábrica de feijão autowire lida com dependências no caso?
Este é realmente um padrão ruim. Se é assim que você realmente usa o MyBean, por que não apenas ter um construtor com o AnotherBean como parâmetro. Algo como: codeprivate @Autowired AnotherBean bean; public void doStuff () {Objeto MyBean = novo MyBean (bean); } code. Parece ser como com todas essas anotações pessoas ficam realmente confuso e simplesmente não usam o padrão básico que estavam no SDK Java desde o dia 1. :(
Eu concordo - a Primavera redefiniu o idioma inteiro. Agora usamos interfaces como classes concretas, métodos como instâncias de classe e todo tipo de métodos complicados e pesados ​​de código para fazer o que você costumava fazer com um design novo e decente.
@ Denis, se o MyBean tiver dependências que a classe real não precisa, você estará registrando dependências que na verdade não existem, apenas para instanciar uma classe, então não há realmente nenhuma diferença.
— 21716 Dalton
Você também pode marcar seu MyClass com a anotação @Configurable:
Então, no momento da criação, ele injeta automaticamente suas dependências. Você também deve ter <context:spring-configured/>em seu contexto de aplicativo xml.
Galz666, seu método parece muito mais limpo para o que eu quero fazer. No entanto, não consigo fazê-lo funcionar. Não tenho arquivo xml e estou usando inteiramente a configuração do Java. Existe um equivalente a <context:spring-configured/>?
— masstroy
Esta é uma solução limpa, mas requer um pouco mais de esforço: você deve usar a tecelagem em tempo de carregamento, como mostra o iimuhin acima, ou adicionar o compilador AspectJ ao projeto. O tempo de carregamento, como o nome sugere, causará custos adicionais no tempo de execução.
Acabei de ter a mesma necessidade e, no meu caso, já era a lógica dentro da classe java não gerenciável do Spring que tinha acesso ApplicationContext. Inspirado por scaffman. Resolvido por:
— rand0m86
Eu queria compartilhar minha solução que segue a @Configurableabordagem brieflymencionada na resposta @ glaz666 porque
A resposta de @skaffman tem quase 10 anos e isso não significa que não seja bom o suficiente ou que não funcione
A resposta de @ glaz666 é breve e realmente não me ajudou a resolver meu problema, mas me indicou a direção certa
Spring Boot 2.0.3 com Spring Neo4j & Aop starts(que é irrelevante de qualquer maneira)
Instanciar um bean quando Spring Bootestiver pronto usando a @Configurableabordagem (usando ApplicationRunner)
Eu precisava seguir as etapas abaixo para fazê-lo funcionar
O @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false)a ser colocado em cima do seu Beanque deve ser instanciado manualmente. No meu caso, o Beanque deve ser instanciado manualmente possui @Autowiredserviços, portanto, os adereços para a anotação acima.
Anotar principal da Primavera de inicialização XXXApplicaiton.java(ou o arquivo que é anotado com @SpringBootApplication) com o @EnableSpringConfigurede@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
Adicione as dependências no seu arquivo de construção (por exemplo, build.gradle ou pom.xml, dependendo de qual você usa) compile('org.springframework.boot:spring-boot-starter-aop')ecompile('org.springframework:spring-aspects:5.0.7.RELEASE')
O novo + Beanque está anotado em @Configurablequalquer lugar e suas dependências devem ser conectadas automaticamente.
* No que diz respeito ao ponto 3 acima, estou ciente de que o org.springframework.boot:spring-boot-starter-aoppuxa transitivamente o spring-aop(como mostrado aqui a seguir ), mas, no meu caso, o Eclipse falhou ao resolver as @EnableSpringConfiguredanotações, por isso adicionei explicitamente a spring-aopdependência além do iniciador. Se você enfrentar o mesmo problema, apenas declare a dependência ou aventure-se a descobrir