ultima springboot proyecto pom generate java spring

java - proyecto - springboot 2



Referencias opcionales Spring Bean (5)

En mi aplicación, estoy usando ContextLoaderListener para cargar archivos de contexto de muchos archivos jar usando:

<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/contextBeans.xml</param-value> </context-param>

Esto significa que puedo hacer referencia a los frijoles de otros tarros sin hacer importación.

En la aplicación hay múltiples opciones de implementación y en algunos despliegues se pueden excluir. Para apoyar eso, me gustaría que algunas referencias de bean sean opcionales. Por ejemplo:

<bean id="mainAppBean" class="com.someapp.MyApplication"> <constructor-arg index="0" ref="localBean"/> <constructor-arg index="1" ref="optionalBeanReference1"/> <constructor-arg index="2" ref="optionalBeanReference2"/> </bean>

En el ejemplo anterior, me gustaría tener la opción BeanReference1 igual a cero si no se encuentra la referencia (márquelo como opcional)

¿Se puede hacer esto en primavera? ¿O qué método recomienda para manejar referencias dinámicas?


¿Qué método recomienda para manejar referencias dinámicas?

Creo que la respuesta @Autowired de cristian es buena. Eso llamará a los métodos de establecimiento si los beans de ese tipo están disponibles. Sin embargo, si tiene varios beans del mismo tipo, creo que Spring lanza una excepción. Si no puede usar @Autowired por esta u otra razón, veo un par de soluciones:

  1. Puede crear su clase ApplicationContextAware y buscar los beans en el contexto usted mismo:

    public void setApplicationContext(ApplicationContext applicationContext) { if (applicationContext.containsBean("optionalBeanReference1")) { setOptionalBeanReference1( (OptionalBeanReference1)applicationContext.bean( "optionalBeanReference1"); } ... }

  2. Podrías invertir la dependencia. Cada una de las clases opcionales podría establecerse en mainAppBean. Utilizo esto en ciertas situaciones cuando una dependencia directa causaría bucles u otros problemas.

    <bean id="optionalBeanReference1" class="com.someapp.SomeClass"> <constructor-arg index="0" ref="mainAppBean"/> </bean>

    Luego en el SomeClass:

    public SomeClass(com.someapp.MyApplication mainAppBean) { mainAppBean.setOptionalBeanReference1(this); }

  3. Podría quedarse con su dependencia directa y luego importar un archivo con los beans definidos o importar otro archivo donde defina que los beans tienen valores nulos utilizando un bean de fábrica. Ver este código de fábrica .

Buena suerte.


Con las versiones recientes de Spring (probado con Spring 4.1) y Java Configuration y Java 8, puede usar Opcional en los parámetros, y solo está disponible automáticamente si está disponible.

@Autowired public MyApplication(Optional<YourOptionalObject> maybeObject) { // do something with the optional autowired }


Dado que las referencias de bean en su configuración XML se definen a través del lenguaje de expresión (EL), puede hacer lo siguiente:

<property name="cache" value="#{getObject(''optionalCache'')}" />

que hace uso del método BeanExpressionContext.getObject() . Vea here para más detalles.


Mi mejor conjetura es utilizar autowire -ing con falso requerido. No sé cómo puede expresar esto en XML, pero al usar la configuración de anotación, esto se vería así:

@Autowired(required=false)


No hay un mecanismo incorporado para esto. Sin embargo, podría escribir una implementación FactoryBean bastante trivial para hacer esto por usted, algo como esto:

public class OptionalFactoryBean extends AbstractFactoryBean<Object> implements BeanNameAware { private String beanName; @Override public void setBeanName(String beanName) { this.beanName = BeanFactoryUtils.originalBeanName(beanName); } @Override protected Object createInstance() throws Exception { if (getBeanFactory().containsBean(beanName)) { return getBeanFactory().getBean(beanName); } else { return null; } } @Override public Class<?> getObjectType() { return null; } }

Puedes usarlo así:

<bean id="mainAppBean" class="com.someapp.MyApplication"> <constructor-arg index="0" ref="localBean"/> <constructor-arg index="1"> <bean name="optionalBeanReference1" class="com.someapp.OptionalBeanFactory"/> </constructor-arg> <constructor-arg index="2"> <bean name="optionalBeanReference2" class="com.someapp.OptionalBeanFactory"/> </constructor-arg> </bean>