SpringBoot动态注入Bean

目的:

在程序运行期间,动态添加Bean进入到Spring容器。

目前使用到的场景:

对当当网的ElasticJob进行封装,通过自定义注解@ElasticJob的方式开启分布式定时任务。

当所有的Bean都初始化完成之后,读取使用了@ElasticJob注解的所有Bean,然后创建SpringJobSchedule实例并添加到Spring容器中,实现任务的启动。

实现方式:

1.新建一个普通的Java类

public class Animal {
    private String name;
    private String color;
    private byte age;

    public Animal(String name, String color, byte age) {
        this.name = name;
        this.color = color;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public byte getAge() {
        return age;
    }

    public void setAge(byte age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", age=" + age +
                '}';
    }
}
View Code

2.通过DefaultListableBeanFactory和BeanDefinitionBuilder实现Bean的动态注入

@SpringBootApplication(scanBasePackages = {"org.example.*"})
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(Application.class);
        DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) run.getAutowireCapableBeanFactory();
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Animal.class);
        beanDefinitionBuilder.addConstructorArgValue("喜鹊").addConstructorArgValue("绿色").addConstructorArgValue(3);
        String beanName = "AnimalAutoName";
        //默认单例
        beanDefinitionBuilder.setScope("prototype");
        autowireCapableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        Object bean = run.getBean(beanName);
        Animal animal = (Animal) bean;
        System.out.println(animal.getAge());
        System.out.println(animal.getColor());
        System.out.println(animal.getName());
    }
}
View Code

流程:

 

 在对Bean进行初始化设置时,是通过构造函数进行初始化(要按照构造函数参数顺序进行赋值)还是通过属性进行初始化或者是两者都可以,这完全取决于要动态注入的Bean。

posted @ 2020-05-21 22:14  你学会了吗  阅读(7123)  评论(0编辑  收藏  举报