精通SpringFamework(2) -读取配置文件过程分析

在应用程序员时,无法避免同配置文件打交道,在初学spring时是不是遇到过无法读取配置文件,或者配置文件路径找不到的情况,这篇文章,分析 spiring 读取 配置文件的过程。

一、Spring 读取配置方法

1.1 property-placeholder

 <Context:property-placeholder location="myConfig1.properties,myConfig.properties"/>

1.2 PropertySourcesPlaceholderConfigurer

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:myConfig.properties</value>
            </list>

        </property>

    </bean>

1.3 废弃的PropertyPlaceholderConfigurer

 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
         <property name="locations">
             <array>
                 <value>classpath:config.properties</value>
             </array>
         </property>
     </bean>

二、打印spring 配置

2.1 代码获取profile

Environment environment= context.getEnvironment();
        System.out.println(Arrays.toString(environment.getActiveProfiles()));

2.2获取spring 读取的配置信息

这点可以方便debug 时查看application 是否加载了正确的配置

三、springFramework 结合maven pom 配置profile

3.1 maven中配置profile 文件

 <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <db.driver>com.mysql.jdbc.Driver</db.driver>
                <db.url>jdbc:mysql://localhost:3306/test</db.url>
                <db.username>root</db.username>
                <db.password>root</db.password>
                <activatedProperties>dev</activatedProperties>
            </properties>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <db.driver>com.mysql.jdbc.Driver</db.driver>
                <db.url>jdbc:mysql://localhost:3306/test_db</db.url>
                <db.username>root</db.username>
                <db.password>root</db.password>
                <activatedProperties>test</activatedProperties>
            </properties>
        </profile>

        <profile>
            <id>prd</id>
            <properties>
                <db.driver>com.mysql.jdbc.Driver</db.driver>
                <db.url>jdbc:mysql://localhost:3306/test_db</db.url>
                <db.username>root</db.username>
                <db.password>root</db.password>
                <activatedProperties>prd</activatedProperties>
            </properties>
        </profile>
    </profiles>

true 默认激活配置

idea 针对maven 中 profile 中支持

在这里插入图片描述

可以在idea 中手动选择环境

2.2 spring 配置文件中动态读取maven 中profile 信息

maven 中增加配置:

 <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

编译项目:

spring.profiles.active=@activatedProperties@
[email protected]@

编译之后 字段替换了值
在这里插入图片描述

3.3 springFramework 中 配置profile

整个配置文件是 dev

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:Context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
       profile="dev">


    <bean id="helloWorld" class="com.fancv.spring.HelloWorld">
        <property name="message" value="Hello World!"/>
        <property name="age" value="21"/>
    </bean>
    <bean id="person2" class="com.fancv.spring.HelloWorld">
        <constructor-arg index="0" value="lisi"/>
        <constructor-arg index="1" value="21"/>
    </bean>
    <Context:component-scan base-package="com.fancv.scan"/>

</beans>

针对 bean 配置 profile

<beans profile="prd">
        <bean id="person2" class="com.fancv.spring.HelloWorld">
            <constructor-arg index="0" value="lisi"/>
            <constructor-arg index="1" value="21"/>
        </bean>
    </beans>

注意:此教程针对 spring 原理的理解分析,不建议在生产环境中使用,为什么不用springBoot呢?

四、Spring激活profile 的方法

spring在确定profile的值时根据 spring.profiles.active 和spring.profiles.default 两个值

ClassPathXmlApplicationContext 中默认了spring.profiles.default 的值时default
而且ClassPathXmlApplicationContext 初始化的ApplicationContext 不能在代码中修改 Environment

spring 提供了多种方式激活profile

4.1.作为DispatcherServlet 初始化参数

针对spring web 项目,如果你不打算使用spring mvc 就不会有机会初始化
org.springframework.web.servlet.DispatcherServlet

4.2 作为Web应用的上下文参数

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>demo</display-name>

    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>test</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>spring-web</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-web</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

4.3代码修改 Spring上下文

/**
         * 可以修改 ConfigurableEnvironment
         */
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().setActiveProfiles("dev");
        ctx.register(Car.class);
        ctx.refresh();

4.4 作为JNDI条目

JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一.
JNDI 是Tomcat 配置内容,目前很少在生产系统中使用

4.5 作为环境变量

4.6 作为jvm的系统属性

4.7 集成测试类中使用 @Activeprofiles

五、spring @condition 注解

使用示例:

项目启动的时候校验其配置

@Configuration
@Conditional(CloudConfigurationCheck.InnerCondition.class)
public class CloudConfigurationCheck implements InitializingBean {
    
    
    @Autowired(required = false)
    ConfigServerInstanceProvider provider;
    
    @Value("${spring.cloud.config.discovery.service-id:configserver}")
    String serviceName;

    @Override
    public void afterPropertiesSet() throws Exception {
    
    
        if (provider == null) {
    
    
            throw new BeanCreationException("请务必使用配置中心,强制脱离配置中心请使用 --spring.native-boot.enabled=true 作为启动参数");
        }
        try {
    
    
            provider.getConfigServerInstance(serviceName);
        } catch (IllegalStateException e) {
    
    

            throw new BeanCreationException("配置中心必须正确连接,请检查配置或网络,强制脱离配置中心请使用 --spring.native-boot.enabled=true 作为启动参数",e);
        }
    }

    public static class InnerCondition implements Condition{
    
    

        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    
    
            return !context.getEnvironment().containsProperty("spring.native-boot.enabled")||context.getEnvironment().getProperty("spring.native-boot.enabled","false").equals("false");
        }
    }
}

参考资料:
https://www.cnblogs.com/lvbinbin2yujie/p/10274663.html
https://cloud.tencent.com/developer/article/1497520

源码:https://github.com/andycom/SpringFirst

猜你喜欢

转载自blog.csdn.net/keep_learn/article/details/114649433