zoukankan      html  css  js  c++  java
  • Spring 监听器 ApplicationListener 的使用

    前言

    在项目中我们经常会遇到在项目的各个阶段进行一些操作,此时可以使用 ApplicationListener 接口搭配 ApplicationEvent 类使用 。

    ApplicationListener 支持的事件类型

    1. ApplicationFailedEvent:该事件为spring boot启动失败时的操作

    2. ApplicationPreparedEvent:上下文context准备时触发

    3. ApplicationReadyEvent:上下文已经准备完毕的时候触发

    4. ApplicationStartedEvent:spring boot 启动监听类

    5. SpringApplicationEvent:获取SpringApplication

    6. ApplicationEnvironmentPreparedEvent:环境事先准备

    ApplicationEvent 

    首先继承结构如下

    EventObject
    --ApplicationEvent
    --SpringApplicationEvent
    --ApplicationEnvironmentPreparedEvent

    近期在工作中需要通过不同的运行环境(dev、prod)加载不同的配置文件,故本次只针对ApplicationEnvironmentPreparedEvent做不同环境下配置文件加载为例。

    1、编写自己的Listener实现 ApplicationListener 接口,监听事件使用ApplicationEnvironmentPreparedEvent,实现onApplicationEvent,以下示例可实现加载不同环境下的多个文件。

    public class PropertiesListenerConfig implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
        private static final Logger logger = LoggerFactory.getLogger(PropertiesListenerConfig.class);
        private static final ArrayList<String> propertyFileNames = new ArrayList<>();
        private static String env = "dev";
    
        public PropertiesListenerConfig(String[] propertyFileName) {
            propertyFileNames.addAll(Arrays.asList(propertyFileName));
        }
    
        @Override
        public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
            // 读取配置环境
            if (StringUtils.hasText(applicationEnvironmentPreparedEvent.getEnvironment().getActiveProfiles()[0])) {
                env = applicationEnvironmentPreparedEvent.getEnvironment().getActiveProfiles()[0];
            }
            // 加载配置文件
            if (propertyFileNames.size() > 0) {
                for (String propertyFileName : propertyFileNames) {
                    // 配置需要载入的配置文件
                    PropertiesListenerConfig.loadAllProperties(propertyFileName);
                }
            }
        }
    
    
        public static Map<String, String> propertiesMap = null;
    
        private static void processProperties(Properties props) throws BeansException {
            if (propertiesMap == null) {
                propertiesMap = new HashMap<>();
            }
            for (Object key : props.keySet()) {
                String keyStr = key.toString();
                try {
                    // PropertiesLoaderUtils的默认编码是ISO-8859-1,在这里转码一下
                    propertiesMap.put(keyStr, new String(props.getProperty(keyStr).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void loadAllProperties(String propertyFileName) {
            try {
                Properties properties = PropertiesLoaderUtils.loadAllProperties(getEnvPropPath(propertyFileName));
                processProperties(properties);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 根据配置文件名,获取系统环境下的配置文件
         *
         * @param propertyFileName 配置文件名称
         * @return 系统环境下的配置文件
         */
        public static Properties getEnvPropFile(String propertyFileName) {
            Properties properties = new Properties();
            try {
                properties.load(PropertyValues.class.getClassLoader().getResourceAsStream(getEnvPropPath(propertyFileName)));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return properties;
        }
    
        public static String getProperty(String name) {
            return propertiesMap.get(name);
        }
    
        public static Map<String, String> getAllProperty() {
            return propertiesMap;
        }
    
        /**
         * 根据配置文件名,获取系统环境下的配置文件路径
         *
         * @param propertyFileName 配置文件名称
         * @return 系统环境下的配置文件路径
         */
        private static String getEnvPropPath(String propertyFileName) {
            return "config/" + env + "/" + propertyFileName;
        }
    
    }

    2、监听类写完后,将监听类在启动类中加载启动

    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class,org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, org.activiti.spring.boot.SecurityAutoConfiguration.class})
    @Import({DynamicDataSourceConfig.class})
    @EnableAsync
    public class CapApplication extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            SpringApplication application = new SpringApplication(CapApplication.class);
            // 配置文件名称
            String[] config = {"fdfs_client.properties"};
            // 根据application.yml配置环境,初始化配置文件
            application.addListeners(new PropertiesListenerConfig(config));
            application.run(args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(CapApplication.class);
        }
    }

    3、在使用过程中,即可获得对应配置文件对象。

    Properties pro = PropertiesListenerConfig.getEnvPropFile("fdfs_client.properties")

     4、如果不想将配置文件写入启动类中,也可以在启动类中只添加Listeners,在ApplicationListener实现类中去加载配置文件列表,如下:

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(CapApplication.class);
        application.addListeners(new PropertiesListenerConfig());
        application.run();
    }

    5、需要在监听实现类中提供默认构造函数,并在实现的onApplicationEvent方法中获取配置文件列表。

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
        // 读取配置环境
        if (StringUtils.hasText(applicationEnvironmentPreparedEvent.getEnvironment().getActiveProfiles()[0])) {
            env = applicationEnvironmentPreparedEvent.getEnvironment().getActiveProfiles()[0];
        }
        logger.info("当前运行环境{}",env);
        propertyFileNames.add("fdfs_client.properties");
        // 加载配置文件
        if (propertyFileNames.size() > 0) {
            for (String propertyFileName : propertyFileNames) {
                // 配置需要载入的配置文件
                PropertiesListenerConfig.loadAllProperties(propertyFileName);
            }
        }
    }

    6、除了在启动类中增加监听外,也可以在application.yml中配置需要监听的类,效果相同。

    下一节记录配置ApplicationListener的多种方式。。。

     

  • 相关阅读:
    机器学习-识别手写数字0-9
    tensorflow深度学习-mnist数据集读入-初试
    TensorFlow 2.0 最基础的线性回归
    cuDNN 环境变量-默认安装路径
    INT104-lab2
    [蓝桥杯][历届试题][dfs][割点]危险系数
    2021-03-19:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的最大子矩形,内部有多少个1。
    2021-03-17:手写代码:单链表插入排序。
    2021-03-16:手写代码:单链表归并排序。
    2021-03-15:手写代码:单链表选择排序。
  • 原文地址:https://www.cnblogs.com/lansetuerqi/p/14847546.html
Copyright © 2011-2022 走看看