tutorial framework java spring

java - spring framework tutorial



¿Cuál es la mejor manera de inicializar un frijol? (5)

En primavera, puede inicializar un bean haciendo que applicationContext.xml invoque un constructor, o puede establecer propiedades en el bean. ¿Cuáles son las compensaciones entre los dos enfoques? ¿Es mejor tener un constructor (que hace cumplir el contrato de tener todo lo que necesita en un método) o es mejor tener todas las propiedades (lo que le da flexibilidad para inyectar selectivamente, por ejemplo, cuando se prueban unidades).

¿Cuáles son las compensaciones (entre escribir un bean que usa un constructor para establecer su estado inicial o usar propiedades y tal vez un método afterProperties ())?


No sé la versión que está usando actualmente, pero si es Spring 2.5 también podría considerar usar la anotación @Autowired para ciertos casos. Esto de grueso solo funciona para referencias a otros granos y no para cadenas, etc. como en el ejemplo de Lycony.

Le ahorra la carga de crear setters y / o constructores y mucha configuración. Un pequeño ejemplo:

public class MyPersonBean { @Autowired private PersonManager personManager; public void doSomething() { this.personManager.doSomething(); } }

Y en tu archivo de configuración:

<context:annotation-config/>

El autoenvío se realiza por tipo, por lo que si tiene un bean del tipo PersonManager, lo inyectará en el campo anotado. En caso de que tenga más beans de ese tipo, puede usar la anotación @Qualifier para diferenciarlos ...

Puede encontrar más información sobre el autoenvío en la documentación de referencia de Spring

Empecé a usar @Autowired en combinación con el escaneo de componentes en mi proyecto anterior y debo decir que me deshice de más del 90% de mis archivos de configuración de Spring.


Las compensaciones:

Constructor: Beneficios: puede ser muy simple, esp. con tres o menos propiedades para inicializar. One-shot, no / minimal extra configuration de la que preocuparse.

Inconvenientes: se deben crear múltiples constructores para varias situaciones. Los constructores no se heredan, por lo que las clases deben llamar a super () y proporcionar constructores duplicados para permitir el comportamiento anterior.

Setters: Beneficios: los niños heredan setters, por lo que las propiedades se pueden anular fácilmente para influir en el comportamiento después de la construcción. Se pueden especificar múltiples propiedades de forma unificada sin buscar firmas de métodos diferentes (convenciones JavaBeans)

Inconvenientes: cada setter debe invocarse explícitamente para cada propiedad. Lleva a algunas clases que tienen un gran número de propiedades establecidas explícitamente.


No estoy seguro de que haya una "mejor" forma de inicializar un frijol. Creo que hay ventajas y desventajas para cada uno, y dependiendo de la situación, uno u otro podrían ser apropiados. Esta ciertamente no es una lista exhaustiva, pero aquí hay algunas cosas que considerar.

Usar un constructor te permite tener un bean inmutable. Los objetos inmutables son buenos si puedes colocarlos en tu diseño. No requieren copia, acceso serializado u otro manejo especial entre hilos. Si tiene setters, su objeto no es inmutable. Usar un constructor también asegura que el objeto esté inicializado correctamente. Después de que el constructor finaliza, el objeto es válido. Si su objeto requiere el uso de setters para inicializarlo, es posible tener un objeto no válido.

Por otro lado, el uso de constructores a menudo conduce a un problema telescópico. Muchas veces necesitará muchos constructores diferentes, la mayoría de los cuales serán un superconjunto de otro constructor. Muchas veces estos son por conveniencia. Por ejemplo:

public class Person { public Person(String name) { ... } public Person(String name, String phone) { ... } public Person(String name, String phone, String email) { ... } }

Una alternativa a esto que me gusta mucho es el llamado patrón de generador "mejorado" presentado por Josh Bloch en JavaOne. Puedes ver esto en su libro "Effective Java, Second Edition". Si observa la forma en que se usa el patrón, también resolverá su problema del método "afterProperties". El patrón del generador garantizará que el objeto esté correctamente inicializado.

Aquí hay una publicación de blog adicional sobre el patrón: http://www.screaming-penguin.com/node/7598

No estoy seguro de que esto se ajuste a sus requisitos de primavera, pero, en general, soy un gran admirador de la construcción.


IMO la principal ventaja de la inyección de constructor es que es compatible con la inmutabilidad. Sin embargo, si una clase tiene más de 3 dependencias, esto requiere proporcionar un constructor que tome una gran cantidad de parámetros, lo cual es difícil de manejar.

Al usar Setter- @PostConstruct , prefiero usar la anotación @PostConstruct para identificar el método de inicialización. Esto implica un acoplamiento más flexible con el marco Spring que el método afterProperties() que mencionas (en realidad, creo que es afterPropertiesSet() ). Otra opción es el atributo de método init del elemento <bean> .


También puedes usar @Resource para autoaumentar en lugar de @Autowired , esto funciona como autowire byName para que no tengas que preocuparte si hay más beans con el mismo tipo (de ofc también puedes manejar eso con @Qualifier , pero yo lo haría solo recomiendo que para describir una característica de un frijol). Realmente depende de tu caso de uso cuál será el mejor, así que debes evaluarlo para tu situación y decidir después.