java - framework - spring dependency injection application context
Auto inyección con Spring (6)
Dado el código anterior, no veo una dependencia cíclica. Usted inyecta una instancia de Servicio en UserService. La implementación del Servicio inyectado no necesariamente necesita ser otro UserService, por lo que no existe una dependencia cíclica.
No veo por qué se inyectaría un UserService en UserService, pero espero que sea una prueba teórica o tal.
BeanNotFoundException
el siguiente código con Spring 3.x que falló con BeanNotFoundException
y debería hacerlo según las respuestas a una pregunta que hice antes: ¿Puedo inyectar la misma clase usando Spring?
@Service
public class UserService implements Service{
@Autowired
private Service self;
}
Como estaba intentando esto con Java 6, encontré que el siguiente código funciona bien:
@Service(value = "someService")
public class UserService implements Service{
@Resource(name = "someService")
private Service self;
}
pero no entiendo cómo se resuelve la dependencia cíclica.
EDITAR:
Aquí está el mensaje de error. El OP lo mencionó en un comentario sobre una de las respuestas:
Causado por: org.springframework.beans.factory.NoSuchBeanDefinitionException: no se ha encontrado ningún bean de tipo [com.spring.service.Service] encontrado para la dependencia: se espera al menos 1 bean que califique como candidato de autowire para esta dependencia. Anotaciones de dependencia: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}
Este código también funciona:
@Service
public class UserService implements Service {
@Autowired
private ApplicationContext applicationContext;
private Service self;
@PostConstruct
private void init() {
self = applicationContext.getBean(UserService.class);
}
}
No sé por qué, pero parece que Spring puede obtener el bean de ApplicationContext
si se crea , pero no se inicializa . @Autowired
funciona antes de la inicialización y no puede encontrar el mismo bean. Entonces, @Resource
puede funcionar luego de @Autowired
y antes de @PostConstruct
.
Pero no sé, solo estoy especulando. De todos modos, buena pregunta.
Parece que Spring crea y configura un objeto y luego lo coloca en el contexto de búsqueda de beans. Pero, en el caso de Java, creo que crea el objeto y lo vincula con el nombre y durante la configuración cuando el objeto se busca por el nombre que se encuentra en el contexto.
Por cierto, la solución más elegante al problema de auto invocación es usar AspectJ Load-Time Weaving para sus proxies transaccionales (o cualquier proxy introducido por AOP que esté usando).
Por ejemplo, con la gestión de transacciones basada en anotaciones, puede usar el modo "aspectj" de la siguiente manera:
<tx:annotation-driven mode="aspectj" />
Tenga en cuenta que el modo predeterminado es "proxy" (es decir, proxies dinámicos JDK).
Saludos,
Sam
Obtener el proxy AOP del objeto en sí pregunta sugiere un enfoque alternativo hacky con AopContext.currentProxy()
que puede ser adecuado para casos especiales.
Actualización: febrero de 2016
Self autowiring será oficialmente compatible con Spring Framework 4.3. La implementación se puede ver en este commit de GitHub .
La razón definitiva por la que no puede auto-conectarse es que la implementación del método DefaultListableBeanFactory.findAutowireCandidates(String, Class, DependencyDescriptor)
de Spring excluye explícitamente la posibilidad. Esto es visible en el siguiente fragmento de código de este método:
for (String candidateName : candidateNames) {
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
FYI: el nombre del frijol (es decir, el frijol que intenta autoaumentarse) es beanName
. That bean es, de hecho, un candidato de autowire, pero la condición if anterior devuelve false (ya que candidateName
de hecho es igual a beanName
). Por lo tanto, simplemente no puede autoaumentar un bean consigo mismo (al menos no a partir del Spring 3.1 M1).
Ahora, en cuanto a si esto es intencional o no, semánticamente hablando, esa es otra pregunta. ;)
Preguntaré a Juergen y veré lo que tiene que decir.
Saludos,
Sam (Core Spring Committer)
ps He abierto un problema Spring JIRA para considerar la posibilidad de autoautenticar por tipo usando @Autowired. Siéntase libre de mirar o votar este problema aquí: https://jira.springsource.org/browse/SPR-8450