java - springframework - Inyectar frijoles en una clase fuera del contexto administrado de Spring
spring framework 5 (7)
La búsqueda de infinitos combos de autowire inyectan bean de primavera en la aplicación pojo, en este caso, beanaware, etc., me rodearon aquí pero esto no me proporcionó una solución lo suficientemente completa.
Esta es una implementación / tutorial mucho mejor de esta IMO: espero que ayude a todos los gustos, finalmente me ayudó.
Soy un usuario final de uno de los productos de mi empresa. No es muy adecuado para la integración en Spring, sin embargo, soy capaz de manejar el contexto y recuperar el bean requerido por su nombre. Sin embargo, aún me gustaría saber si es posible inyectar un frijol en esta clase, incluso si la clase no está administrada por Spring.
Aclaración: la misma aplicación que está administrando el ciclo de vida de alguna clase MyClass, también está administrando el ciclo de vida del contexto de Spring. Spring no tiene ningún conocimiento de la instancia de MyClass, y me gustaría saber cómo proporcionar la instancia al contexto, pero no puedo crear la instancia en el contexto mismo.
Otra forma de hacerlo es usar AspectJ. Esta es la forma recomendada de inyectar Spring beans en objetos no administrados que se crean con el new
operador. Vea esto para más detalles:
http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html
Si desea crear un objeto fuera del contexto de Spring y poner ese objeto disponible para su inyección en otros beans que están en el contexto de Spring, puede seguir los pasos de este artículo .
Básicamente, crea un contexto de aplicación padre e inserta su objeto externo en este contexto padre como singleton. Luego, crea el contexto principal de la aplicación (por ejemplo, desde archivos xml), con el contexto de la aplicación principal como su elemento principal.
Object externalObject = ...
GenericApplicationContext parent = new StaticApplicationContext();
parent.getBeanFactory().registerSingleton( "externalObject", externalObject );
parent.refresh();
ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);
Tenga cuidado de que en la versión más antigua de Spring, hay un problema de seguridad de subprocesos con la fábrica de frijoles http://jira.springframework.org/browse/SPR-4672
Una forma de traer un frijol a Spring a pesar de que su fabricación es externa es usar una clase de ayuda marcada como @Configuration
que tiene un método (marcado con @Bean
) que realmente hace la instancia y la devuelve a través de Spring (que hace su inyección de propiedad y generación de proxy en ese punto).
No estoy muy seguro de qué alcance necesita; con un prototype
, obtendrás un grano fresco en cada lugar.
@Configuration
public class FooBarMaker {
@Bean(autowire = Autowire.BY_TYPE)
@Scope("prototype")
public FooBar makeAFooBar() {
// You probably need to do some more work in here, I imagine
return new FooBar();
}
}
Puede inyectar propiedades requeridas para la fabricación en el bean @Configuration
. (Utilizo esto para crear instancias de una interfaz donde el nombre de la clase para instanciar se define en tiempo de ejecución).
supongamos que tiene la siguiente cadena de dependencia:
A -> B -> C -> x -> y -> Z
A, B, C son granos manejados por resorte (construidos y manejados por un armazón de muelles) x, y son POJOs realmente simples que fueron construidos por su aplicación, sin asistencia de primavera
ahora, si quiere eso, obtendrá una referencia a Z usando un resorte que necesita tener un "mango" para el resorte ApplicationContext
Una forma de hacerlo es implementar la interfaz ApplicationContextAware . En este caso, sugeriría que A, B o C implementarán esta interfaz y almacenarán la referencia de applicationContext en un miembro estático.
entonces tomemos la Clase C, por ejemplo:
class C implmenets ApplicationContextAware{
public static ApplicationContex ac;
void setApplicationContext(ApplicationContext applicationContext) {
ac = applicationContext;
}
.............
}
ahora, en clase y deberías tener:
(Z)(C.ac.getBean("classZ")).doSomething()
HTH - Yonatan
Puedes hacerlo:
ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
someBeanNotCreatedBySpring,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
Puede usar @Autowired
y demás en YourClass
para especificar los campos que se inyectarán, etc.