在应用程序员时,无法避免同配置文件打交道,在初学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