动态添加bean交给spring管理
最新项目整合uflo,前端有个选项是根据后端的一个实现类的个数以及属性生成的。这样如果后期要调整选项的个数,就得改代码,添加实现类,这样比较麻烦。然后就想着写一个通用实现类,属性由配置信息赋值,生成的个数也由配置信息决定。
话不多说,上代码:
@Data
public class GlzcProviderImpl extends GlzcProcessProviderImpl {
private String processFileType;
private String processFileName;
@Override
public String getName() {
return processFileName;
}
@Override
public String getPrefix() {
return this.prefix;
}
public String getProcessFileType() {
return this.processFileType;
}
}
目标就是根据配置信息将这个实现类生成多个,同时要将属性信息修改为配置信息的值。
public class BeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@SneakyThrows
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
String ufloConfig = (String) PropertiesUtils.getCommonYml("uflo");
String[] split = ufloConfig.split(";");
for (String s : split) {
String[] split1 = s.split(",");
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(GlzcProviderImpl.class).getBeanDefinition(); // 定义创建bean的信息
registry.registerBeanDefinition(split1[1], beanDefinition); // 向beanFactory中注册一个bean
}
}
}
这个类的作用是动态的将类的配置信息交给BeanFactory,随后生成对应的bean交给spring管理。
@Service
@Import(BeanDefinitionRegistrar.class)
public class LastExceededDataListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private ApplicationContext applicationContext;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
String ufloConfig = (String) PropertiesUtils.getCommonYml("uflo");
String company = (String) PropertiesUtils.getCommonYml("company.name");
String[] split = ufloConfig.split(";");
if (event.getApplicationContext().getParent() == null) {
for (String s : split) {
String[] split1 = s.split(",");
GlzcProviderImpl bean = (GlzcProviderImpl) applicationContext.getBean(split1[1]);
bean.setProcessFileName(split1[1]);
bean.setProcessFileType(split1[0]);
}
}
}
}
这个类继承了ApplicationListener,作用就是在spring容器的bean都加载完之后再执行onApplicationEvent这个方法。同时有个@import()注解的意思是在加载这个bean到spring容器中的时候会去加载()里的类。
/**
* Created by pojor on 2019/1/4.
*/
public class PropertiesUtils {
private static String PROPERTY_NAME = "application.yml";
public static Object getCommonYml(Object key){
Resource resource = new ClassPathResource(PROPERTY_NAME);
Properties properties = null;
try {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(resource);
properties = yamlFactory.getObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return properties.get(key);
}
}
这是个工具类,作用是将手动的读取yml里的配置信息。在spring的启动过程中,@Value和@autowire这些注解的生效是比较晚的,如果在生成实现类的过程中使用这些注解,是取不到值的。
uflo: aa,啊啊啊啊;bb,啵啵啵啵啵啵;cc,踩踩踩踩踩踩
配置信息用分号逗号隔开,一个分号对应一个实现类。
最后,有什么问题大家一起交流呀。