Proficient in SpringFamework (2)-Analysis of the process of reading configuration files

As an application programmer, it is inevitable to deal with configuration files. When you first learned spring, did you encounter situations where the configuration file could not be read or the configuration file path could not be found? This article analyzes the process of spiring reading the configuration file .

One, Spring read configuration method

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

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

Two, print spring configuration

2.1 Code acquisition profile

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

2.2 Get the configuration information read by spring

This is convenient for checking whether the application has loaded the correct configuration when debugging

Three, springFramework combined with maven pom configuration profile

3.1 Configure profile file in maven

 <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 default activation configuration

idea is for the support in the profile in maven

Insert picture description here

You can manually select the environment in idea

2.2 Dynamically read profile information in maven in spring configuration file

Add configuration in maven:

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

Compile the project:

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

Field replaced value after compilation
Insert picture description here

3.3 Configure profile in springFramework

The entire configuration file is 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>

Configure profile for bean

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

Note: This tutorial aims to understand and analyze the principles of spring. It is not recommended to use it in a production environment. Why not use springBoot?

Fourth, Spring activates the profile method

When spring determines the value of the profile, it is based on the two values ​​of spring.profiles.active and spring.profiles.default

The default value of spring.profiles.default in
ClassPathXmlApplicationContext is default and the ApplicationContext initialized by ClassPathXmlApplicationContext cannot be modified in the code.

Spring provides a variety of ways to activate the profile

4.1. As the DispatcherServlet initialization parameter

For spring web projects, if you do not plan to use spring mvc, you will not have the opportunity to initialize
org.springframework.web.servlet.DispatcherServlet

4.2 As the context parameter of the web application

<?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 code modification Spring context

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

4.4 as a JNDI entry

JNDI is the Java Naming and Directory Interface (Java Naming and Directory Interface), which is one of the important specifications in the J2EE specification.
JNDI is the configuration content of Tomcat, which is rarely used in production systems at present

4.5 As an environment variable

4.6 as a system property of jvm

4.7 Use @Activeprofiles in the integration test

Five, spring @condition annotation

Example of use:

Verify the configuration when the project starts

@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");
        }
    }
}

Reference materials:
https://www.cnblogs.com/lvbinbin2yujie/p/10274663.html
https://cloud.tencent.com/developer/article/1497520

Source code: https://github.com/andycom/SpringFirst

Guess you like

Origin blog.csdn.net/keep_learn/article/details/114649433