Spring中抽象類中使用EmbeddedValueResolverAware和@PostConstruct獲取配置文件中的參數值

個人需求:

  我有一個 abstract class 中包含了不少子類中須要用到的公共方法和變量,我想在抽象類中java

使用@Value獲取*.properties中的值。可是@Value必需要在Spring的Bean生命週期管理下才能web

使用,好比類被@Controller、@Service、@Component等註解標註。那我就想在抽象類中獲取spring

*.properties中的值,怎麼辦?spring-mvc

我項目的大概狀況:mvc

  web.xmlapp

<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.xmlide

<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>

準備代碼:

一、寫一個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);
    }

}

二、在須要獲取*.properties值的抽象類中引入PropertiesUtil工具類,並使用@PostConstruct註解進行初始化。oop

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 classfetch

因此在debug的過程當中這個被@PostConstruct註解的init()方法在Spring容器啓動的時候會運行8次,可是4個class是能經過

propertiesUtil獲取到值的,而4個abstract class 是獲取不到值的。因此就把第一次獲取到的properties中的值用map存下來。

(確定有更好的方法可是我沒有發現,但願你們能夠告訴我)

相關文章
相關標籤/搜索