Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 552
alan Avatar asked Sep 12 '26 19:09

alan


1 Answers

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>
like image 56
Artem Bilan Avatar answered Sep 16 '26 08:09

Artem Bilan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!