spring 5 动态创建Bean

在之前的版本中,我们是用BeanFactoryPostProcessor来实现bean的动态创建的,但是spring 5 原生就支持了动态创建bean。
从spring 5.x 开始,官方在GenericApplicationContext提供了registerBean方法。这里我们可以看到,其原理还是用BeanDefinition来实现的。

public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
      @Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {

   ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition(beanClass);
   if (supplier != null) {
      beanDefinition.setInstanceSupplier(supplier);
   }
   for (BeanDefinitionCustomizer customizer : customizers) {
      customizer.customize(beanDefinition);
   }

   String nameToUse = (beanName != null ? beanName : beanClass.getName());
   registerBeanDefinition(nameToUse, beanDefinition);
}

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

   this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}


我们试试效果
写一个class

public class PersonService {
    public void say(){
        System.out.println("this is a person");
    }
}


使用CommandLineRunner在容器启动后创建

@Component
public class BeanRegisterRunner implements CommandLineRunner {

    @Autowired
    private GenericApplicationContext genericApplicationContext;

    @Override
    public void run(String... args) throws Exception {
        genericApplicationContext.registerBean(PersonService.class, PersonService::new);
    }
}


调用

@RestController
@RequestMapping(value = "user")
public class UserController {

    @Autowired
    @Lazy //由于是在容器启动后创建,所以这里需要加个@Lazy
    private PersonService personService;

    @GetMapping(value = "person-say")
    public void personSay(){
        personService.say();
    }
}


请求这个接口,控制台成功打印。所以,达到预期。

基于BeanFactoryPostProcessor动态创建Bean
https://www.ithere.net/article/1422088308742520834


关于作者

落雁沙
非典型码农
获得点赞
文章被阅读