⑴ Springboot 读取配置文件原理
Springboot 读取配置文件(application.yaml, application.properties)的过程发生在SpringApplication#prepareEnvironment() 阶段,而prepareEnvironment又属于整个Springboot 应用启动的非常前置阶段,因为Environment的准备是后续bean创建的基础。让我们来一探启动是的详细code。除去StopWatch这些code,可以发现prepareEnvironment 发生在SpringApplication#run 这在整个应用启动的多步实质性操作中几乎是第一步。
而prepareEnvironment中最重要的是通过触发listener(EventPublishingRunListener)来通过#multicastEvent发出。
而#multicastEvent的实现其实也很简单,找到相关的监听的listener,然后一个个的调用他们的Listener#onApplicationEvent(event)方法,而这其中就包括了处理configuration文件的listener。 在Springboot 2.4.0 之前这个处理configuration 文件的lister是ConfigFileApplicationListener,在2.4.0之后,处理configuration 文件的lister是,并且对configuration文件的加载做了较大的改变,导致一些行为可能出现了变化,这也就是下面要详细讲的内容。
Springboot 2.4.0之后,configuration 文件的load顺序按照优先级是如下顺序(序号大的会被小的覆盖):
和之前版本比较,整体的属性加载顺序并无调整,只有Application properties(14,15)这里有顺序的调整,具体调整为:
如果存在多个active的profiles,例如[Test, Dev], 那么对于同时存在两个profile 配置文件中的配置,后面的profile里的配置(Dev)会覆盖前面profile(Test)里配置的值。
前面讲了这么多,终于要引出Springboot 2.4之后配置文件加载的行为变化了。
考虑这样的情况,如果我想在跑Springboot test的时候指定特定的profile,那么可以在Test class中加入@ActiveProfile(“Test”)。 如果我的应用中存在的某个自定义listener中,会根据当前environment 设置profile,如env.addActiveProfile(“Dev”)。 当前就会有两个active profile,由于springboot-test会在调用application#run 前利用DefaultActiveProfilesResolver把@ActiveProfile注解定义的profile(Test)先加入了active的profile,等test run的时候 env.addActiveProfile(“Dev”) 又会把”Dev”也作为active profile 加入,这时候当前的active profile便为[“Test”, “Dev”]。
据上面介绍,后面的profile(Dev)对应的configuration 会覆盖前面的(Test)。可Springboot 2.4.0之前的版本为我们做了调整,让Test class中@ActiveProfile内定义的profile所对应的配置文件成为最高优先级。
刚才提到在Springboot 2.4.0 之前这个处理configuration 文件的lister是ConfigFileApplicationListener,我们 来看看ConfigFileApplicationListener的相关code。
查看initializeProfiles(),发现此时对profile的顺序做了调整,将activatedViaProperty (Test) 放在最后add,于是profile的顺序就变成了[Dev, Test]。
在profiles.poll()时原本profile的顺序已经倒了过来,已经变为[Dev, Test], 在load()方法中由于后置的Test profile,application-Test.yaml中的值最终生效了。
可是到了Springboot2.4.0之后,ConfigFileApplicationListener被deprecated了,取而代之的是,通过调用来完成configuration加载。 .java
.java
只是老老实实的set了active profile,并没有调换profile的顺序。最后调用定义在spring.factories中的resource loader class来load 配置文件。
YamlPropertySourceLoader.java
插一句,Springboot为我们提供了很好的yaml文件parse的code,当你需要解析yaml文件时不妨直接参考Springboot的YamlPropertySourceLoader
这样一旦应用升级到Springboot 2.4.0之后相同的test code会使用application-Dev.yaml中配置的值,造成了test结果的改变。 如果要解决这个问题,根据上面介绍的配置文件优先级顺序,可以在@SpringbootTest中设置properties 来作为最终的配置覆盖当前profile对应的配置。
了解一个框架很不容易,一个小小的变化都有可能造成应用的行为变化,唯有刨根问底,不断总结才是framework人解决一切问题的不变的方法论。
⑵ Spring中读取bean配置文件的几种方式
BeanFactory允许InputStream作为构造函数的参数,也可以org.springframework.core.io.Resource接口。下面这个例子是用ClassPathResource作为参数:Resource resource = new ClassPathResource("bean.xml");BeanFactory factory = new XmlBeanFactory(resource);ActionBean action = (ActionBean) factory.getBean("actionBean"); 如果同一个Bean在配置文件有多个bean的定义,则用下面的方法取得所有的对象:Resource resource = new ClassPathResource("bean.xml");ListableBeanFactory factory = new XmlBeanFactory(resource);Map helloBeans = factory.getBeansOfType(ActionBean.class, false, false);
⑶ springmvc中如何从配置文件中读取信息
1、第一来步,先新建一个.properties文件源,app.properties里面内容admin=admintest=test2、第二步,新建一个xml文件,在applicationContext.xml,<!– 用来解析Java Properties属性文件值(注意class指定的类)–><bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:app.properties</value></list></property></bean><!– 把properties里面的信息读进来: –><bean id="report" class="java.lang.String"><constructor-arg value="${admin}"/></bean>
⑷ Java读取配置文件的几种方法
在现实工作中,我们常常需要保存一些系统配置信息,大家一般都会选择配置文件来完成,本文根据笔者工作中用到的读取配置文件的方法小小总结一下,主要叙述的是spring读取配置文件的方法。一、读取xml配置文件(一)新建一个java beanpackage chb.demo.vo;public class HelloBean {private String helloWorld;public String getHelloWorld() {return helloWorld;}public void setHelloWorld(String helloWorld) {this.helloWorld = helloWorld;}}(二)构造一个配置文件?xml version=”1.0″ encoding=”UTF-8″?!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “”beansbean id=”helloBean” class=”chb.demo.vo.HelloBean”property name=”helloWorld”valueHello!chb!/value/property/bean/beans(三)读取xml文件1.利用ApplicationContext context = new (“beanConfig.xml”);HelloBean helloBean = (HelloBean)context.getBean(“helloBean”);System.out.println(helloBean.getHelloWorld());2.利用FileSystemResource读取Resource rs = new FileSystemResource(“D:/software/tomcat/webapps/springWebDemo/WEB-INF/classes/beanConfig.xml”);BeanFactory factory = new XmlBeanFactory(rs);HelloBean helloBean = (HelloBean)factory.getBean(“helloBean”);System.out.println(helloBean.getHelloWorld());值得注意的是:利用FileSystemResource,则配置文件必须放在project直接目录下,或者写明绝对路径,否则就会抛出找不到文件的异常。二、读取properties配置文拿镇件这里介绍两种启敬技术:利用spring读取properties 文件和利用java.util.Properties读取(一)利用spring读取properties 文件我们还利用上面的HelloBean.java文件,构造如下beanConfig.properties文件:helloBean.class=chb.demo.vo.HelloBeanhelloBean.helloWorld=Hello!chb!属性文件中的”helloBean”名称即是Bean的别名设定,.class用于指定类来消旁粗源。然后利用org.springframework.beans.factory.support.来读取属性文件BeanDefinitionRegistry reg = new DefaultListableBeanFactory(); reader = new (reg);reader.loadBeanDefinitions(new ClassPathResource(“beanConfig.properties”));BeanFactory factory = (BeanFactory)reg;HelloBean helloBean = (HelloBean)factory.getBean(“helloBean”);System.out.println(helloBean.getHelloWorld());(二)利用java.util.Properties读取属性文件比如,我们构造一个ipConfig.properties来保存服务器ip地址和端口,如:ip=192.168.0.1port=8080则,我们可以用如下程序来获得服务器配置信息:InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(“ipConfig.properties”);Properties p = new Properties();try {p.load(inputStream);} catch (IOException e1) {e1.printStackTrace();}System.out.println(“ip:”+p.getProperty(“ip”)+”,port:”+p.getProperty(“port”));
⑸ SpringBoot有几种读取配置的方式
常见的读取配置的方式有三种:第一、@Value注解,比较常用的一种方式。也支持与@propertySource注解何用,指定使用的配置文件第二、@Configuration注解,读取配置到类中,批量注入配置属性第三、Environment对象,获取配置文件中所有的属性的对象如果你想掌握时下热门微服务技术栈,跟上时代技术步伐,就去黑马程序员官网视频库看免费视频。
⑹ 如何在spring中读取properties配置文件里面的信息
一般来说。我们会将一些配置的信息放在。properties文件中。 然后使用${}将配置文件中的信息读取至spring的配置文件。 那么我们如何在spring读取properties文件呢。 1.首先。我们要先在spring配置文件中。定义一个专门读取properties文件的类. 例: <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath*:jdbc.properties</value> <!–要是有多个配置文件,只需在这里继续添加即可 –> </list> </property> </bean> 这里为什么用locations(还有一个location) 是因为。一般来说。我们的项目里面。配置文件可能存在多个。 就算是只有一个。那将来新添加的话。只需在下面再加一个value标签即可。 而不必再重新改动太多。(当然。性能上是否有影响,这个以当前这种服务器的配置来说。是基科可以忽略不计的)。 然后我们就可以在jdbc.properties文件中填写具体的配置信息了。 <!– 配置C3P0数据源 –> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass"> <value>${jdbc.driverClassName}</value> </property> <property name="jdbcUrl"> <value>${jdbc.url}</value> </property> <property name="user"> <value>${jdbc.username}</value> </property> <property name="password"> <value>${jdbc.password}</value> </property> </bean> jdbc.properties文件写的信息。 jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=root 附加一个列子: <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>file:/data/pc-config/passport.properties</value> <value>classpath:memcached.properties</value> </list> </property> </bean> classpath:是指的当前类文件的目录下。 file:在window下是指的当前分区(比如你的项目是放在d盘,则是在d:/data/pc-config/passport.properties) 在linux下,则是当前路径下的文件/data/pc-config/passport.properties 转载仅供参考,版权属于原作者。祝你愉快,满意请~~哦