某些情况下静态的配置信息无法满足系统需求,需要根据静态配置动态生成bean注册到spring中。
为啥要动态注册bean?#
某些情况下静态的配置信息无法满足系统需求,需要根据静态配置动态生成bean注册到spring中。在写一些工具的时候会用到的,原本打算写一个类似 Fegin 的小组件。于是有了这个研究动机。但后来网上找到了我想要的开源项目,就不重复造轮子了,但是技术点还是研究了一下。 感兴趣的可以去看看这个项目:Forest
啥时候注册bean?#
太晚了肯定不行啊,@Autowired不等人,在Autowired注入之后注册肯定报错啊,想都不要想。那么就要在Autowired之前。
咋注册呢?#
Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。
思路一
搞一个类实实现BeanPostProcessor,ApplicationContextAware接口 让它早于AutowiredAnnotationBeanPostProcessor运行。BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。but这个我没搞出来不知的问题出在哪里,有机会再研究研究。
思路二
搞一个类实现BeanFactoryPostProcessor接口.这是个啥接口呢?实现该接口,可以在spring的bean创建之前,修改bean的定义属性。不废话直接贴代码。
public class MyBeanFactoryPostProcessor implements ApplicationContextAware, BeanFactoryPostProcessor { private static ApplicationContext applicationContext; private String packageS; public String getPackageS() { return packageS; } public void setPackageS(String packageS) { this.packageS = packageS; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { MyBeanFactoryPostProcessor.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } public static Object getBean(String beanName) { return applicationContext.getBean(beanName); } public static <T>T getBean(String beanName , Class<T>clazz) { return applicationContext.getBean(beanName , clazz); } /** * 此方法会在bean初始化完成但未实例化时调用 */ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { //beanFactory 也可以拿到当前系统从已经初始化好的bean,也可以做一些修改 //设置了扫描路径则则可以根据扫描包扫描相应的注解 System.out.println("packageS==================="+packageS); //获取BeanFactory DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory(); //模拟扫描到的bean,用动态代理等等方式创建 //创建bean信息. BeanDefinitionBuilder beanDefinitionBuilder =BeanDefinitionBuilder.genericBeanDefinition(RestBean.class); beanDefinitionBuilder.addPropertyValue("name","张三"); //动态注册bean. defaultListableBeanFactory.registerBeanDefinition("restBean",beanDefinitionBuilder.getBeanDefinition()); //注册进spring上下文的bean可以获取一下看看 BeanDefinition bd = beanFactory.getBeanDefinition("restBean"); } }
javaConfig
@Configuration public class Config { @Bean public MyBeanFactoryPostProcessor getMyBeanFactoryPostProcessor() { MyBeanFactoryPostProcessor sss = new MyBeanFactoryPostProcessor(); sss.setPackageS("com.xxxx"); return sss; } }
现在就可以在spring管理的任何类中使用了
@Autowired RestBean restBean;
代码地址:BeanLoad
知乎上看到一个专栏,学到不少东西。有兴趣可以关注一下。晓风轻
评论 (0)