你需要即时声明新bean并将它们注入Spring的应用程序上下文中,就像它们只是普通bean一样,这意味着它们必须经受代理,后处理等 *** 作,即它们必须经受Spring bean生命周期的约束。 。
请参阅
BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法 javadocs。这正是你所需要的,因为它使你可以在装入常规bean定义之后 但 实例化任何单个bean之前修改Spring的应用程序上下文。
@Configurationpublic class ConfigLoader implements BeanDefinitionRegistryPostProcessor { private final List<String> configurations; public ConfigLoader() { this.configurations = new linkedList<>(); // TODO Get names of different configurations, just the names! // i.e. You could manually read from some config file // or scan classpath by yourself to find classes // that implement MyConfiguration interface. // (You can even hardpre config names to start seeing how this works) // important: you can't autowire anything yet, // because Spring has not instantiated any bean so far! for (String readConfigurationName : readConfigurationNames) { this.configurations.add(readConfigurationName); } } public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // iterate over your configurations and create the beans definitions it needs for (String configName : this.configurations) { this.quartzConfiguration(configName, registry); this.quartzModule(configName, registry); this.healthCheck(configName, registry); // etc. } } private void quartzConfiguration(String configName, BeanDefinitionRegistry registry) throws BeansException { String beanName = configName + "_QuartzConfiguration"; BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(QuartzConfiguration.class).setLazyInit(true); // TODO Add what the bean needs to be properly initialized // i.e. constructor arguments, properties, shutdown methods, etc // BeanDefinitionBuilder let's you add whatever you need // Now add the bean definition with given bean name registry.registerBeanDefinition(beanName, builder.getBeanDefinition()); } private void quartzModule(String configName, BeanDefinitionRegistry registry) throws BeansException { String beanName = configName + "_QuartzModule"; BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(QuartzModule.class).setLazyInit(true); builder.addConstructorArgReference(configName + "_QuartzConfiguration"); // quartz configuration bean as constructor argument // Now add the bean definition with given bean name registry.registerBeanDefinition(beanName, builder.getBeanDefinition()); } private void healthCheck(String configName, BeanDefinitionRegistry registry) throws BeansException { String beanName = configName + "_HealthCheck"; BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HealthCheck.class).setLazyInit(true); // TODO Add what the bean needs to be properly initialized // i.e. constructor arguments, properties, shutdown methods, etc // BeanDefinitionBuilder let's you add whatever you need // Now add the bean definition with given bean name registry.registerBeanDefinition(beanName, builder.getBeanDefinition()); } // And so on for other beans...}
这有效地声明了你需要的bean,并将它们注入Spring的应用程序上下文中,每种配置都有一组bean。你必须依靠某种命名模式,然后在需要的地方通过名称自动连接bean:
@Servicepublic class MyService { @Resource(name="config1_QuartzConfiguration") private QuartzConfiguration config1_QuartzConfiguration; @Resource(name="config1_QuartzModule") private QuartzModule config1_QuartzModule; @Resource(name="config1_HealthCheck") private HealthCheck config1_HealthCheck; ...}
笔记:
如果你要从文件中手动读取配置名称,请使用Spring的ClassPathResource.getInputStream()。
如果你自己扫描类路径,强烈建议你使用令人惊叹的Reflections库。
你必须为每个bean定义手动设置所有属性和依赖项。每个bean定义都独立于其他bean定义,即,你不能重用它们,也不能在另一个内部设置它们,等等。想想它们就像你在以旧的XML方式声明bean一样。
检查BeanDefinitionBuilder javadocs和GenericBeanDefinition javadocs以获得更多详细信息。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)