alan
alan

Reputation: 131

Dynamic context - autowiring

I am dynamically adding contexts to the application context with the following code:

@Component
@Scope("singleton")
public class DynamicContextLoader implements ApplicationContextAware {

   private static ApplicationContext context;

   private Map<String, InterfacePropertyDto> contextMap;

   @Autowired
   IJpaDao jpaDao;

   @PostConstruct
   public void init() {
      contextMap = (Map<String, InterfacePropertyDto>) context.getBean("contextMap");
      contextMap.forEach((contextName, property) -> {
         String p = jpaDao.getProperty(property.getPropertyName(), property.getPropertyType());
         if (p != null) {
            ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
                    new String[]{"/META-INF/spring/integration/" + contextName},
                    false, context);
            ctx.refresh();
         }
      });


   }

   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      context = applicationContext;
   }
}

This works well and all the beans defined in the new context are created. However the @Autowired does not work for any of these new beans.

For example a bean defined in the new context as:

<bean id="outboundContractJdbcFileMapper" class="com.......integration.model.contract.ContractMapper"/>

has the following autowiring:

public class ContractMapper implements RowMapper<ContractFile> {

   @Autowired
   IIntegrationDao integrationDao;

   @Override
   public ContractFile mapRow(ResultSet rs, int rowNum) throws SQLException {
      ......
   }
}

At runtime the outboundContractJdbcFileMapper property integrationDao is null.

Is there a way to force the autowiring to occur when the beans are created? I was hoping that ctx.refresh() would do this.

Upvotes: 3

Views: 353

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121177

That doesn't work automatically for the ClassPathXmlApplicationContext. You have to add <context:annotation-config/> to that child context as well:

<xsd:element name="annotation-config">
    <xsd:annotation>
        <xsd:documentation><![CDATA[
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB 3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.

Note: This tag does not activate processing of Spring's @Transactional or EJB 3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.

See javadoc for org.springframework.context.annotation.AnnotationConfigApplicationContext
for information on code-based alternatives to bootstrapping annotation-driven support.
        ]]></xsd:documentation>
    </xsd:annotation>
</xsd:element>

Upvotes: 3

Related Questions