sirve que para example ejemplo component bean anotaciones java spring dependency-injection

java - para - que es spring



Cómo recopilar e inyectar todos los beans de un tipo determinado en la configuración Spring XML (3)

Uno de los acentos más fuertes del marco Spring es el concepto de Inyección de Dependencia . Entiendo que uno de los consejos detrás de esto es separar el mecanismo general de alto nivel de los detalles de bajo nivel (según lo anunciado por el Principio de Inversión de Dependencia ).

Técnicamente, eso se reduce a tener una implementación de frijol para saber lo menos posible acerca de que un frijol sea inyectado como una dependencia, por ejemplo

public class PrintOutBean { private LogicBean logicBean; public void action() { System.out.println(logicBean.humanReadableDetails()); } //... } <bean class="PrintOutBean"> <property name="loginBean" ref="ShoppingCartBean"/> </bean>

Pero, ¿y si quisiera tener un mecanismo de alto nivel operando en múltiples beans dependientes?

public class MenuManagementBean { private Collection<Option> options; public void printOut() { for (Option option:options) { // do something for option } //... } }

Sé que una solución sería usar la anotación @Autowired en el bean singleton, es decir ...

@Autowired private Collection<Option> options;

Pero, ¿no viola el principio de separación? ¿Por qué tengo que especificar qué dependientes tomar en el mismo lugar donde los uso (es decir, la clase MenuManagementBean en mi ejemplo)? ¿Hay alguna forma de inyectar colecciones de beans en la configuración XML como esta (sin ninguna anotación en la clase MMB )?

<bean class="MenuManagementBean"> <property name="options"> <xxx:autowire by-type="MyOptionImpl"/> </property> </bean>



No hay instalaciones listas para usar para hacer esto, no. Sin embargo, si quiere una forma de recopilar todos los beans de un tipo dado en una colección, sin usar una lista @Autowired, entonces es fácil escribir un FactoryBean personalizado para que lo haga por usted:

public class BeanListFactoryBean<T> extends AbstractFactoryBean<Collection<T>> { private Class<T> beanType; private @Autowired ListableBeanFactory beanFactory; @Required public void setBeanType(Class<T> beanType) { this.beanType = beanType; } @Override protected Collection<T> createInstance() throws Exception { return beanFactory.getBeansOfType(beanType).values(); } @Override public Class<?> getObjectType() { return Collection.class; } }

y entonces

<bean class="MenuManagementBean"> <property name="options"> <bean class="BeanListFactoryBean"> <property name="beanType" class="MyOptionImpl.class"/> </bean> </property> </bean>

Sin embargo, todo esto parece un gran esfuerzo para evitar poner @Autowired en su clase original. No es una gran violación de SoC, si es que lo es, no hay dependencia de tiempo de compilación y no se sabe de dónde provienen las options .


Pregunta anterior y en primavera 3.1 es posible:

public class PluginPrototypeTest extends ASpringWebTest { @Autowired Collection<IDummyRepo> repos; @Test public void cacheTest() { assertNotNull(repos); assertEquals(2, repos.size()); for(IDummyRepo r: repos){ System.out.println(r.getName()); } } } @Repository public class DummyRepo implements IDummyRepo { @Override public String getName(){ return "DummyRepo"; } } @Repository public class DummyRepo2 implements IDummyRepo { @Override public String getName(){ return "DummyRepo2"; } }