SpringBoot得到ApplicationContext、动态设置枚举值

SpringBoot得到ApplicationContext

  • 方式一
    • 直接通过启动类返回得到
package com.zbj;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * BeanFactoryApplication
 *
 * @author weigang
 * @create 2019-07-30
 **/
@SpringBootApplication
public class BeanFactoryApplication {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(BeanFactoryApplication.class);
        // 获取 ApplicationContext 方式一
        // 这种方式有缺点 必须要等所有Bean初始化完成才能返回 ApplicationContext
        // 如果在当前类或方法完成bean注册 违背单一原则
        // 网上部分网友使用静态类,完成初始化后设置到静态类中,使用时直接得到ApplicationContext进行操作 类似于 ApplicationContextUtils
        // 静态方法是全局的 所有方法都可以修改 存在安全风险
        ConfigurableApplicationContext applicationContext = springApplication.run(args);
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();

        Order order = new Order("sdqeadse213", "asfas", "浙江省杭州市");
        // 动态注入Bean
        beanFactory.registerSingleton("order", order);
    }
}
* 然后通过静态方法设置成全局变量 启动后任何地方后可以获取(ApplicationContextUtils)
package com.zbj;

import org.springframework.context.ApplicationContext;

/**
 * ApplicationContextUtils
 *
 * @author weigang
 * @create 2019-07-31
 **/
public class ApplicationContextUtils {

    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext applicationContext) {
        ApplicationContextUtils.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static  T getBean(Class requiredType) {
        return applicationContext.getBean(requiredType);
    }
}
  • 方式二
    • 通过监听器得到applicationContext
package com.zbj;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/**
 * CustomApplicationListener
 *
 * @author weigang
 * @create 2019-07-30
 **/
@Component
public class CustomApplicationListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 获取 ApplicationContext 方式二
        // 这时直接引用 @Autowired DefaultListableBeanFactory defaultListableBeanFactory 为空 由Listener执行时间可知
        ApplicationContext applicationContext = event.getApplicationContext();
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        Order order = new Order("333333333333", "444444444", "5555555");
        // 动态注入Bean
        defaultListableBeanFactory.registerSingleton("order2", order);
    }
}
  • 由于方式一保存在全局的静态属性中 任何人都可以设置,而且从启动类中获取,违背单一职责

动态设置枚举值

  • 新增枚举工具类 DynamicEnumUtils (参见源码)
  • 测试类参见 EnumMain
  • 注意事项 不管动态设置枚举值对象中有几个属性值,都不用修改源码(业务上三个属性值,导致去修改源码 结果离正确的道路越走越远)

源码 https://gitee.com/weigang200820/bean-factory-init
参考博文 https://blog.csdn.net/qq_35530330/article/details/85647826

你可能感兴趣的:(Java,Spring,Boot,知识总结,动态设置,枚举)