• Spring中抽象类中使用EmbeddedValueResolverAware和@PostConstruct获取配置文件中的参数值


    我的需求:

      我有一个 abstract class 中包含了很多子类中需要用到的公共方法和变量,我想在抽象类中

    使用@Value获取*.properties中的值。但是@Value必须要在Spring的Bean生命周期管理下才能

    使用,比如类被@Controller、@Service、@Component等注解标注。那我就想在抽象类中获取

    *.properties中的值,怎么办?

    我项目的大概情况:

      web.xml

    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring/spring-context.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <listener>
            <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener>
        <servlet>
            <servlet-name>mvc-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:/spring/spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>mvc-dispatcher</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

      spring-context.xml

    <context:component-scan base-package="com.hyxf.amlfetch" />
    
    <context:annotation-config />
    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <list>
                <!--<value>classpath*:*.properties</value>--> <--这样也可以,只是感觉不是很明了-->
                <value>classpath*:config.properties</value>
                <value>classpath*:jdbc.properties</value>
                <value>classpath*:log4j.properties</value>
            </list>
        </property>
    </bean>

    准备代码:

    1、写一个PropertiesUtil工具类,实现EmbeddedValueResolverAware 

    package com.hyxf.amlfetch.common.util;
    
    import org.springframework.context.EmbeddedValueResolverAware;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringValueResolver;
    
    /**
     * 获取properties文件中的value的工具类
     */
    @Component
    public class PropertiesUtil implements EmbeddedValueResolverAware {
        private StringValueResolver stringValueResolver;
    
        @Override
        public void setEmbeddedValueResolver(StringValueResolver resolver) {
            stringValueResolver = resolver;
        }
        public String getPropertiesValue(String name){
            return stringValueResolver.resolveStringValue(name);
        }
    
    }

    2、在需要获取*.properties值的抽象类中引入PropertiesUtil工具类,并使用@PostConstruct注解进行初始化。

    package com.hyxf.amlfetch.biz.service.coop;
    
    import com.hyxf.amlfetch.common.util.PropertiesUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.hyxf.amlfetch.common.util.Logger;
    import com.hyxf.amlfetch.dao.mapper.aml.OdsT2aBatchMapper;
    import org.springframework.util.StringUtils;
    
    import javax.annotation.PostConstruct;
    import java.util.HashMap;
    import java.util.Map;
    
    public abstract class AbstractFetchService<T> implements FetchService<T> {
    
        protected Logger logger = Logger.getLogger(this.getClass());
        
        @Autowired
        protected OdsT2aBatchMapper odsT2aBatchMapper;
    
        @Autowired
        private PropertiesUtil propertiesUtil;
    
        private static final String DB_READ_NUM_KEY = "each_db_read_num";
    
        private static final String DB_WRITE_NUM_KEY = "each_db_write_num";
    
        private static Map<String, String> dbNum = new HashMap<>();
    
        /**
         * 索引位置
         */
        protected static final Integer FROM_INDEX = 0;
    
        /**
         * 加载配置文件的值
         * 抽象类不能够使用@Value,在spring容器初始话的时候来获取这个值
         */
        @PostConstruct
        public void init() {
            String eachDbWriteNum = propertiesUtil.getPropertiesValue("${" + DB_WRITE_NUM_KEY + "}");
            if(StringUtils.isEmpty(dbNum.get(DB_WRITE_NUM_KEY))) {
                dbNum.put(DB_WRITE_NUM_KEY, eachDbWriteNum);
            }
            String eachDbReadNum = propertiesUtil.getPropertiesValue("${" + DB_READ_NUM_KEY + "}");
            if(StringUtils.isEmpty(dbNum.get(DB_READ_NUM_KEY))) {
                dbNum.put(DB_READ_NUM_KEY, eachDbReadNum);
            }
        }
    
        public Integer getEachDbWriteNum() {
            if(StringUtils.isEmpty(dbNum.get(DB_WRITE_NUM_KEY))) {
                return 0;
            }
            return Integer.parseInt(dbNum.get(DB_WRITE_NUM_KEY));
        }
    
        public Integer getEachDbReadNum() {
            if(StringUtils.isEmpty(dbNum.get(DB_READ_NUM_KEY))) {
                return 0;
            }
            return Integer.parseInt(dbNum.get(DB_READ_NUM_KEY));
        }
    }

      解释一下,为什么这里用了一个static的HashMap,因为这个抽象类有8个子类,其中4个class 和 4个 abstract class

    所以在debug的过程中这个被@PostConstruct注解的init()方法在Spring容器启动的时候会运行8次,但是4个class是能通过

    propertiesUtil获取到值的,而4个abstract class 是获取不到值的。所以就把第一次获取到的properties中的值用map存下来。

    (肯定有更好的方法但是我没有发现,希望大家可以告诉我)

  • 相关阅读:
    如何配置SWRLJess Tab?
    Orz游戏开发框架阅读笔记(一)
    JessDE 在 Eclipse中不能正确安装的问题
    如何在Protege3.4中安装graphviz以便在protege中使用OwlvizTab?
    语义网的学习资源大汇集(转载)
    如何使用Eclipse从Subversion源码服务器下载源码?
    UltraEdit不能对Matlab的M文件进行语法高亮显示问题的解决
    UltraEdit的语法高亮文件网址
    IronPython的致命弱点
    【WPF】用CustomControl打造WPF版的Marquee
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/11075641.html
Copyright © 2020-2023  润新知