Prefacio
Este artículo presenta principalmente el contenido relevante sobre la búsqueda (inyección del método) en la primavera. Se comparte para su referencia y aprendizaje. No diré mucho a continuación. Echemos un vistazo a la introducción detallada juntos:
Esto puede suceder cuando se usa la primavera: un frijol singleton depende de otro frijol no singleton. Si simplemente usa el ensamblaje automático para inyectar dependencias, pueden surgir algunos problemas, como se muestra a continuación:
Clase A para Singleton
@ComponentPublic Class ClassA {@aUtowired private classb classb; public void printClass () {System.out.println ("Esta es clase A:" + esto); classb.printClass (); }}Clase B para no solo
@Componente@scope (value = scope_prototype) public classb classb {public void printClass () {System.out.println ("Esta es la clase B:" + this); }} Aquí, Clase A adopta el alcance de singleton predeterminado y se basa en la Clase B. El alcance de la clase B es prototipo, por lo que no es un singleton. En este momento, puede ver el problema de escribir así después de ejecutar una prueba:
@RunWith (SpringRunner.class) @ContextConfiguration (classes = {ClassA.class, classb.class}) Mytest de clase pública {@aUtowired private classA classA; @Test public void simpletest () {for (int i = 0; i <3; i ++) {classA.printClass (); }}}El resultado de la salida es:
Esta es la clase A: clase@282003e1
Esta es la clase B: classb@7fad8c79
Esta es la clase A: clase@282003e1
Esta es la clase B: classb@7fad8c79
Esta es la clase A: clase@282003e1
Esta es la clase B: classb@7fad8c79
Como puede ver, el código hash de ambas clases es el mismo en las tres salidas. Es comprensible que el valor de la clase A permanezca sin cambios porque es un singleton, pero el alcance de la clase B es un prototipo pero también mantiene el código hash sin cambios, que parece haberse convertido en un singleton.
La razón de esta situación es que el alcance de la Clase A es el singleton predeterminado, por lo que el contexto solo creará el frijol de Clase A una vez, por lo que solo hay una posibilidad de inyectar dependencias, y el contenedor no puede proporcionar a Clase A una nueva Clase B cada vez.
No tan buena solución
Para resolver el problema anterior, puede hacer algunas modificaciones a la Clase A para implementar ApplicationContextAware.
@ComponentPublic Class ClassA implementa ApplicationContextAware {private ApplicationContext ApplicationContext; public void printClass () {System.out.println ("Esta es clase A:" + esto); getClassB (). printClass (); } public classb getClassb () {return ApplicationContext.getBean (classb.class); } public void setApplicationContext (ApplicationContext ApplicationContext) lanza Beansexception {this.ApplicationContext = ApplicationContext; }}De esta manera, puede encontrar manualmente un nuevo bean en el contexto cada vez que necesita ir a la clase B. Después de ejecutar otra prueba, obtuve el siguiente resultado:
Esta es la Clase A: com.devhao.classa@4df828d7
Esta es la clase B: com.devhao.classb@31206beb
Esta es la Clase A: com.devhao.classa@4df828d7
Esta es la clase B: com.devhao.classb@3e77a1ed
Esta es la Clase A: com.devhao.classa@4df828d7
Esta es la clase B: com.devhao.classb@3ffcd140
Puede ver que el código hash de clase A permanece sin cambios en las tres salidas, mientras que la clase B es diferente cada vez, lo que muestra que el problema se ha resuelto y la nueva instancia se usa cada vez que se llama.
Sin embargo, este método de escritura está fuertemente junto con la primavera, y Spring proporciona otra forma de reducir la invasividad.
@Buscar
Spring proporciona una anotación llamada @lookup, que es una anotación que funciona en el método. El método marcado por él será anulado. Luego, de acuerdo con el tipo de valor de retorno, el contenedor llama al método getBean () de la factura de bean para devolver un bean.
@ComponentPublic Class ClassA {public void printClass () {System.out.println ("Esto es clase A:" + this); getClassB (). printClass (); } @Lookup public classb getClassb () {return null; }} Se puede encontrar que es mucho más simple y que ya no está fuertemente junto con la primavera. Ejecutar la prueba nuevamente aún puede obtener la salida correcta.
El valor de retorno del método anotado ya no es importante, porque el contenedor generará dinámicamente una subclase y luego reescribirá/implementará el método anotado, y finalmente se llama al método de subclase.
El método de @lookup utilizado debe cumplir con la siguiente firma:
<Public | Protected> [Resumen] <Turn-type> themethodName (no-arguments);
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.