自‘愚’自乐

spring动态注册bean

自‘愚’自乐 Spring

为啥要动态注册bean?

某些情况下静态的配置信息无法满足系统需求,需要根据静态配置动态生成bean注册到spring中。

啥时候注册bean?

太晚了肯定不行啊,@Autowired不等人,在Autowired注入之后注册肯定报错啊,想都不要想。那么就要在Autowired之前。

咋注册呢?

Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。

  1. 思路一

    搞一个类实实现BeanPostProcessor,ApplicationContextAware接口 让它早于AutowiredAnnotationBeanPostProcessor运行。BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。but这个我没搞出来不知道咋整。于是作罢。

  2. 思路二

    搞一个类实现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

    晓风轻的专栏文章给我很多启示,学习了很多,大家有空可以关注一下。晓风轻

    转载请注明出处—-by 王雁

自‘愚’自乐
纯粹开心的私人境地