• 125417

    文章

  • 803

    评论

  • 12

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

Spring动态注册bean

服了这份高薪指南,涨多少你说了算>>

 

 

为什么需要动态注册bean

大部分时候,静态的配置信息即可满足系统需求。但是某些场景下,我们需要根据静态配置中的信息动态生成bean,此时就需要动态注册bean的功能。

如:

用户定义一个如下的接口,而接口的实现则由框架生成,不需要用户自行编写,此时实现类就需要动态注册到容器中。

 

@Rest("http://localhost:8081/test")
public interface IRequestDemo {

	@GET
	ResultBean get1();

	@GET("/get2")
	ResultBean getWithKey(@Param("key") String key);

	@GET("/get3")
	ResultBean getWithMultKey(@Param("key1") String key,     
	     @Param("key2") String key2);
	
}

@componet
public class test {
  @Autowired
  IRequestDemo demo;

  public String test() {
	String msg = "<h1>invoke remote rest result</h1>";

	ResultBean get1 = demo.get1();

	msg += "<br/>get1 result=" + get1;

	ResultBean get2 = demo.getWithKey("key-------");

	msg += "<br/>get2 result=" + get2;

	ResultBean get3 = demo.getWithMultKey("key11111", "key22222");

	msg += "<br/>get3 result=" + get3;

	return msg;
  }
}

代码片段来自我同事[晓风轻][1]的项目[MyRestUtil][2]

 

动态注册bean的api

Spring中的bean定义都保存在 **BeanDefinitionRegistry** 接口中,单例的bean的实例都保存在 **SingletonBeanRegistry** 接口中。

因此动态注册bean也分为了两种方式:

 

1. 使用BeanDefinitionRegistry接口的void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException 方法

2. 使用SingletonBeanRegistry接口的void registerSingleton(String beanName, Object singletonObject) 方法

 

两者区别在于使用前者时,Spring容器会根据BeanDefinition实例化bean实例,而使用后者时,bean实例就是传递给registerSingleton方法的对象。

 

DefaultListableBeanFactory接口同时实现了这两个接口,在实践中通常会使用这个接口。

 

在普通bean中进行动态注册

可以在任何获得了BeanDefinitionRegistry或者SingletonBeanRegistry实例的地方进行动态注册。

但是如果bean不是在BeanFactoryPostProcessor中被注册,那么该bean则无法被**BeanPostProcessor**处理,即无法对其应用aop、Bean Validation等功能。

 

在**BeanFactoryPostProcessor**中进行动态注册

在Spring容器的启动过程中,BeanFactory载入bean的定义后会立刻执行BeanFactoryPostProcessor,此时动态注册bean,则可以保证动态注册的bean被BeanPostProcessor处理,并且可以保证其的实例化和初始化总是先于依赖它的bean。

 

例子

在BeanFactoryPostProcessor注册

@Component
@Slf4j
public class PersonBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory
                = (DefaultListableBeanFactory) beanFactory;

        //注册Bean定义,容器根据定义返回bean
        log.info("register personManager1>>>>>>>>>>>>>>>>");
        BeanDefinitionBuilder beanDefinitionBuilder =
                BeanDefinitionBuilder.genericBeanDefinition(PersonManager.class);
        beanDefinitionBuilder.addPropertyReference("personDao", "personDao");
        BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
        defaultListableBeanFactory.registerBeanDefinition("personManager1", personManagerBeanDefinition);

        //注册bean实例
        log.info("register personManager2>>>>>>>>>>>>>>>>");
        PersonDao personDao = beanFactory.getBean(PersonDao.class);
        PersonManager personManager = new PersonManager();
        personManager.setPersonDao(personDao);
        beanFactory.registerSingleton("personManager2", personManager);

    }
}

在普通bean中注册

@RestController
@Slf4j
public class PersonManagerRegisterController {

    /**
     * The Application context.
     */
    @Autowired
    GenericApplicationContext applicationContext;

    /**
     * The Bean factory.
     */
    @Autowired
    ConfigurableBeanFactory beanFactory;

    /**
     * 动态注册bean,此处注册的bean没有AOP的支持
     * curl http://localhost:8080/registerPersonManager
     */
    @GetMapping("/registerPersonManager")
    public void registerPersonManager() {
        PersonDao personDao = applicationContext.getBean(PersonDao.class);
        PersonManager personManager = new PersonManager();
        personManager.setPersonDao(personDao);
        beanFactory.registerSingleton("personManager3", personManager);

    }
... ...

 


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客