黑马程序员技术交流社区

标题: 【上海校区】 java 静态代码块和spring @value等注解注入顺序 [打印本页]

作者: 不二晨    时间: 2018-12-14 09:35
标题: 【上海校区】 java 静态代码块和spring @value等注解注入顺序
今天在引用yml配置文件的时候,因为用到了继承的静态代码块。类与类有继承关系的静态代码块是先执行父类静态代码块再执行子类静态代码块,这个问题不用说。

今天探索的是与spring相关的执行顺序

我在项目启动的时候需要去加载部分配置文件,这些配置文件的信息在子类的静态代码块需要使用的。跑项目的时候子类引用父类的属性一直报空指针。

父类代码:

package com.pinyu.system.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;

import com.pinyu.system.web.controller.AppInfoController;

/**
* @author ypp
* 创建时间:2018年12月11日 上午10:12:11
* @Description: TODO(用一句话描述该文件做什么)
*/
@Component
@SpringBootConfiguration
@PropertySource("classpath:application.yml")
public class YmlPropertiesUtils {
       
        private static Logger logger = LogManager.getLogger(YmlPropertiesUtils.class);

        @Value("${spring.profiles.active}")
        protected static String profilesActive;

        public static String getProfilesActive() {
                return profilesActive;
        }
       
}
子类代码 :

package com.pinyu.system.global.config.quartz;

import java.io.IOException;
import java.util.Properties;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import com.pinyu.system.global.GlobalConstants;
import com.pinyu.system.utils.YmlPropertiesUtils;

/**
* @author ypp 创建时间:2018年12月11日 上午10:03:52
* @Description: TODO(用一句话描述该文件做什么)
*/
public class QuartzPropertiesUtils extends YmlPropertiesUtils {

        private static Properties quartzProperties;
       
        private static ClassPathResource quartzClassPathResource;

        static {
                try {
                        if (profilesActive.equals(GlobalConstants.PROFILE_ACTIVE_DEV)) {
                                quartzClassPathResource = new ClassPathResource("/quartz.properties");
                        } else if(profilesActive.equals(GlobalConstants.PROFILE_ACTIVE_TEST)){
                                quartzClassPathResource = new ClassPathResource("/test/quartz-test.properties");
                        }
                        quartzProperties = PropertiesLoaderUtils.loadProperties(quartzClassPathResource);
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

        public static Properties getQuartzProperties() {
                return quartzProperties;
        }

        public static ClassPathResource getQuartzClassPathResource() {
                return quartzClassPathResource;
        }
}
在用到profilesActive这个的时候,一直是null。于是去研究了相关执行的顺序。

java static 静态代码块是最先执行的,然后再是spring 相关注入。这样按照上面的思路是获取不到profilesActive值得。因为静态代码块先加载,项目启动就会报错。

于是把父类也用静态代码块来进行获取,子类在父类静态代码块后执行,自然可以获取到。问题解决。

代码如下:

package com.pinyu.system.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;

import com.pinyu.system.web.controller.AppInfoController;

/**
* @author ypp
* 创建时间:2018年12月11日 上午10:12:11
* @Description: TODO(用一句话描述该文件做什么)
*/
//@Component
//@SpringBootConfiguration
//@PropertySource("classpath:application.yml")
public class YmlPropertiesUtils {
       
        private static Logger logger = LogManager.getLogger(YmlPropertiesUtils.class);

//        @Value("${spring.profiles.active}")
        protected static String profilesActive;

        public static String getProfilesActive() {
                return profilesActive;
        }

        static{
                Yaml yaml = new Yaml();
        URL url = YmlPropertiesUtils.class.getClassLoader().getResource("application.yml");
        if (url != null) {
            //获取application.yaml文件中的配置数据,然后转换为obj,
                        try {
//                                Object obj= yaml.load(new FileInputStream(url.getFile()));
                                Map map =(Map)yaml.load(new FileInputStream(url.getFile()));
                                Map spring =(Map)map.get("spring");
                                Map profiles =(Map)spring.get("profiles");
                                profilesActive =(String) profiles.get("active");
                        } catch (FileNotFoundException e) {
                                e.printStackTrace();
                                logger.info("配置初始化错误");
                        }
        }
        }
}
主要记录一个知识点,java静态代码块和spring 注解执行的顺序
---------------------
【转载】仅作分享,侵删
作者:ypp91zr
原文:https://blog.csdn.net/ypp91zr/article/details/84954395



作者: 不二晨    时间: 2018-12-18 17:46
奈斯




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2