在一此场景下,如果需要动态的将某个类注册spring容器中,利用BeanDefinitionBuilder就可以达到这个目的。做个简单的demo实验,定义一个类Person:

@Setter
@Getter
public class Person {

    private String name;

    private String age;
}

手动注册bean的示例类PersonBeanRegiser,它实现了BeanFactoryAware接口,能够获取到Spring工厂类,因BeanFactory是一个接口,通过调试可知,Spring窗口注入的工厂实现类是DefaultListableBeanFactory,通过其源码可以看到,这个Bean工厂类实现了BeanDefinitionRegistry接口,通过这个接口的registerBeanDefinition方法,就可以将bean注册到Spring容器了。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
@Component
public class PersonBeanRegiser implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @PostConstruct
    public void register(){
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Person.class);
        builder.addPropertyValue("name", "张三");
        builder.addPropertyValue("age", 20);
        //重点
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) this.beanFactory;
        registry.registerBeanDefinition("person", builder.getBeanDefinition());
    }

    /**
     *
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(PersonBeanRegiser.class);
        Person person = ctx.getBean(Person.class);
        System.out.println(person.getName());
    }
}

通过执行main方法,可以正常打印出name值:张三

发表评论