Auto-injeção com mola

Eu tentei o seguinte código com Spring 3.x que falhou com BeanNotFoundException e deve de acordo com as respostas de uma pergunta que eu perguntei antes – Posso injetar mesma class usando o Spring?

 @Service public class UserService implements Service{ @Autowired private Service self; } 

Desde que eu estava tentando isso com o Java 6, eu encontrei o seguinte código funciona bem:

 @Service(value = "someService") public class UserService implements Service{ @Resource(name = "someService") private Service self; } 

mas não entendo como isso resolve a dependência cíclica.

EDITAR:
Aqui está a mensagem de erro. O OP mencionou isso em um comentário sobre uma das respostas:

Causado por: org.springframework.beans.factory.NoSuchBeanDefinitionException: Nenhum bean correspondente do tipo [com.spring.service.Service] localizado para dependência: esperado pelo menos 1 bean que se qualifica como candidato autowire para essa dependência. Anotações de dependência: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}

Atualização: fevereiro de 2016

A auto-colocação automática será oficialmente suportada no Spring Framework 4.3. A implementação pode ser vista neste commit do GitHub .


A razão definitiva pela qual você não pode se autowire é que a implementação do método DefaultListableBeanFactory.findAutowireCandidates(String, Class, DependencyDescriptor) da Spring explicitamente exclui a possibilidade. Isso é visível no trecho de código a seguir deste método:

 for (String candidateName : candidateNames) { if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) { result.put(candidateName, getBean(candidateName)); } } 

FYI: o nome do bean (ou seja, o bean que está tentando se autowire) é beanName . Esse bean é, na verdade, um candidato autowire, mas a condição if acima retorna false (já que candidateName na verdade, é igual a beanName ). Assim, você simplesmente não pode autowire um bean consigo mesmo (pelo menos não a partir da Spring 3.1 M1).

Agora, quanto a se isso é ou não um comportamento semântico, isso é outra questão. 😉

Vou perguntar a Juergen e ver o que ele tem a dizer.

Saudações,

Sam (Core Spring Committer)

ps Eu abri uma edição do Spring JIRA para considerar o suporte a auto-autowiring por tipo usando @Autowired. Fique à vontade para assistir ou votar neste assunto aqui: https://jira.springsource.org/browse/SPR-8450

Este código funciona também:

 @Service public class UserService implements Service { @Autowired private ApplicationContext applicationContext; private Service self; @PostConstruct private void init() { self = applicationContext.getBean(UserService.class); } } 

Eu não sei porque, mas parece que o Spring pode obter o bean do ApplicationContext se for criado , mas não inicializado . @Autowired funciona antes da boot e não consegue encontrar o mesmo bean. Então, @Resource talvez funcione após @Autowired e antes de @PostConstruct .

Mas eu não sei, apenas especulando. Enfim, boa pergunta.

A propósito, a solução mais elegante para o problema da auto-chamada é usar o AspectJ Load-Time Weaving para seus proxies transacionais (ou qualquer proxy introduzido pelo AOP que você esteja usando).

Por exemplo, com o gerenciamento de transactions orientado por annotations, você pode usar o modo “aspectj” da seguinte maneira:

  

Observe que o modo padrão é “proxy” (isto é, proxies dynamics do JDK).

Saudações,

Sam

Dado o código acima, não vejo uma dependência cíclica. Você está injetando alguma instância do Serviço no UserService. A implementação do Serviço injetado não precisa necessariamente ser outro UserService, portanto, não há dependência cíclica.

Não vejo por que você injetaria um UserService no UserService, mas espero que seja um teste teórico ou algo assim.

Obter proxy AOP do object em si pergunta sugere alternativa hacky abordagem com AopContext.currentProxy() que pode ser adequado para casos especiais.

Parece que o spring cria e configura um object e, em seguida, coloca-o no contexto de pesquisa do bean. Mas, no caso do Java, acho que ele cria o object e o vincula ao nome e à configuração durante a pesquisa quando o object é procurado pelo nome encontrado no contexto.