2008-10-17 22 views
9

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, al probar unidades)¿Cuál es la mejor manera de inicializar un frijol?

What 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())?

Respuesta

15

No estoy seguro de que haya una "mejor" manera 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.

El uso de un constructor le 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 que tenga 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 la llamada Builder "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í es una entrada de blog adicional de discutir el patrón: http://www.screaming-penguin.com/node/7598

No estoy seguro de que esto se ajusta a su requerimiento de primavera, pero en general, yo soy un gran fan de constructor.

+0

+1 - Muy buena respuesta –

+0

me gusta su respuesta, pero sus enlaces están muertos:/ –

+0

Gracias Maxime, actualicé la publicación con el único enlace que aún queda. :-) – lycono

3

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-injection, 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>.

2

No sé la versión que está utilizando 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 el fichero de configuración:

<context:annotation-config/> 

Autowiring se realiza por tipo, por lo que si usted tiene un frijol del tipo PersonManager, se inyectará en el campo anotado . En caso de que tenga más granos de ese tipo puede utilizar la anotación @Qualifier distinguirlos ...

Puede encontrar más información sobre Autowiring en el Spring Reference Documentation

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

0

Las ventajas y desventajas:

constructor: Beneficios: puede ser muy simple, esp. con tres o menos propiedades para inicializar. Configuración extra de un golpe, no/mínima de la que preocuparse.

inconvenientes: varios constructores deben ser creados por varias situaciones Los constructores no se heredan, por lo que las clases deben llamar a super() y proporcionar constructores duplicados para permitir que el comportamiento anterior.

Setters: Beneficios: Los niños heredan setters, por lo que las propiedades pueden anularse fácilmente para influir en el comportamiento después de la construcción. propiedades múltiples pueden especificarse en forma unificada sin levantar la vista diferentes firmas de método (JavaBeans convenciones)

inconvenientes: Cada colocador debe invocar explícitamente para cada propiedad. Lleva a algunas clases que tienen un gran número de propiedades explícitamente establecidas.

0

También puede utilizar @Resource a Autowire en lugar de @Autowired, esto funciona un poco como Autowire Byname por lo que no tiene que preocuparse si hay más frijoles con el mismo tipo (OFC también se puede manejar eso con @Qualifier, pero solo recomendaría eso 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.

Cuestiones relacionadas