2012-02-24 11 views
23

En mi proyecto, yo estoy tratando de migrar todos los usos decableado primavera por tipo es más lento por la magnitud que el cableado por su nombre

Foo foo = (Foo) beanFactory.getBean("name"); 

en

Foo foo = beanFactory.getBean(Foo.class); 

Las ventajas son evidentes: la seguridad de tipos, código menos intrincado, constantes menos inútiles, etc. Normalmente, tales líneas se ubican en contextos heredados estáticos donde dicho cableado es la única opción.

Todo estuvo bien hasta que un día los usuarios comenzaron a quejarse por la lentitud que resultó de la parte interna de Spring. Así que dispararon hasta un generador de perfiles para encontrar un punto de acceso en

org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)

que tiene una llamada cara a

Class.isAssignableFrom(anotherClass).

he creado rápidamente una pequeña prueba de rendimiento para averiguar la diferencia de velocidad entre el nombre de la cadena y tipo búsquedas se un ferina 350 veces (estoy usando para este StaticApplicationContext FAIW prueba)!

Mientras investigaba esto, encontré SPR-6870 que tiene un gran número de votos pero por alguna razón no se menciona. Esto me llevó a an attempt to solve this problem que mejora significativamente la situación, pero aún es más lento ~ 25 veces que la búsqueda de String! Resulta que este intento solo resuelve la mitad del problema: almacena en caché el nombre del bean para guardar en la iteración de O (n) pero aún tiene que llamar al isAssignableFrom para validar el tipo.

El problema descrito no solo está relacionado con mi escenario, sino también con los beans que usan @Autowired y se puede sentir con dificultad en los casos en que se crean frijoles dentro de un bucle.

Una de las soluciones sería anular uno de los métodos de fábricas de frijoles y almacenar en caché los resultados de las verificaciones is-this-bean-of-the-same-type pero claramente esto debería hacerse en Spring y no en mi propio código.

¿Alguien más está sufriendo un problema similar y ha encontrado una solución para ello?

+0

¿Desea realizar la conexión automática por tipo, pero sin realizar ninguna comprobación de tipo? – GreyBeardedGeek

+0

Quiero la segunda llamada contra el mismo tipo para evitar la costosa comprobación de tipos. O al menos quiero una capacidad para especificar si esto está habilitado o deshabilitado. La creación de objetos es algo tan básico que pequeñas optimizaciones como esta pueden marcar una gran diferencia. – mindas

Respuesta

2

La mayoría de las aplicaciones de Spring combinan elementos al iniciarse, en lugar de extraer beans del contexto en el tiempo de ejecución. Aún así, a menos que cambie el contexto de su aplicación mucho durante la ejecución regular de su aplicación, nunca debería buscar un bean más de una vez.

Dado que, si sus usuarios se quejan de lentitud, parece que su problema real son demasiadas búsquedas de beans; su uso de un medio más lento de hacerlo acaba de surgir el problema real.

Me gustaría moverme a Java Config (configurar sus dependencias en Java, creo que es compatible con Spring 3.0) y configurar su aplicación para conectar todos los beans al inicio. Esto también tiene la ventaja de que su aplicación simplemente no se iniciará si no se pueden cumplir las dependencias.

+0

Creo que lo que realmente quería decir es "mi problema es que estoy usando Spring para esto" :) Respecto a Java Config - sí, esta es una opción de escape, pero sigo pensando que el problema original debe abordarse como parece Afecta (a juzgar por el recuento de votos acumulados) a muchos otros usuarios de Spring. – mindas

+0

Nunca tuve este problema con Spring y lo usé en algunos proyectos bastante grandes. El tiempo de inicio de la aplicación fue bastante lento, pero una vez que las cosas se conectaron, funcionó bien. Automáticamente lo conectamos por su nombre, pero también teníamos alguna configuración XML. Nunca llamamos a getBean directamente. – davetron5000

+0

"Proyectos grandes" pueden tener diferentes escenarios. Tu argumento de que nunca tuviste este problema es discutible. Además, dudo de la sugerencia de que el uso de Java Config (en lugar de XML, por ejemplo) ayude de alguna manera; si se utiliza el mismo tipo de BeanFactory, sufrirá el mismo problema. Es la implementación de instanciación de beans de fábrica que está rota, y no el ensamblaje. – mindas

5

Este problema ahora se resuelve en primavera con la resolución de SPR-6870. Vea los comentarios de resolución allí para más detalles. La corrección está disponible a partir de las versiones 3.2.0.RELEASE y 3.1.2.

+1

Estamos utilizando el resorte 3.2.1 pero la mayor parte del tiempo que la aplicación lo utiliza durante el arranque es de autoenvío por tipo. ¿Alguna sugerencia? –

Cuestiones relacionadas