java 注入配置文件_spring注解注入properties配置文件

spring自3.1版本后,增加了新的注解@PropertySource,用于注解注入配置文件的属性

以前,我们配置读取配置文件,一般都是在XML文件里面配置,其实,这不是很利于维护,毕竟要去XML里面找配置,还需要把对象注册为bean,让xml显得过于臃肿,如下就是以前读取xml读取properties文件的配置,相信不少同学都知道.

classpath:properties/config_userbean.properties

classpath:properties/config_mysql.properties

但是现在我们有注解的形式来配置了,让我们先来看一段源码,是关于注解@PropertySource注解的

bcfca80a99268d58f373f1d13105b162.png

从上面的注释,可以发现,@propertySource注解是自spring 3.1版本开始有的,是一个配置注解,用于注入properties文件的属性的.下面,开始上测试代码吧.

--------------------------------我是分割线--------------------------------------

先看配置文件里面的内容:

userBean.name=hexiaowu

userBean.sex=男

userBean.isflag=true

然后看测试注解注入的类:

@Component

@PropertySource(value = "classpath:properties/config_userbean.properties",ignoreResourceNotFound = true)

public class DemoAnnotation {

//注入peoperties文件里面的属性

@Value("${userBean.name}")

private String propertie_name;

/**

* 使用@value注解注入properties中的属性

* 1.在类名上面使用 @PropertySource("classpath:*") 注解,*代表属性文件路径,可以指向多个配置文件路径

*        如果是多个配置文件,则是 @PropertySource({"classpath:*","classpath:*"....})

*    2.ignoreResourceNotFound=true 表示如果配置文件不存在,则忽略报错

* 3.在字段上直接使用@value注解

* 4.注解内使用${userBean.name} userBean.name 代表属性文件里面的key

* 5.需要新增 PropertySourcesPlaceholderConfigurer 的bean

* 6.在 PropertySourcesPlaceholderConfigurer 增加@bean注解,申明返回的是一个bean,否则会注入不成功

*

*/

@Bean

public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){

return new PropertySourcesPlaceholderConfigurer();

}

public String getPropertie_name() {

return propertie_name;

}

public void setPropertie_name(String propertie_name) {

this.propertie_name = propertie_name;

}

@Override

public String toString() {

return "DemoAnnotation{" +

", propertie_name='" + propertie_name + '\'' +

'}';

有同学会很纳闷了,为什么要返回一个 PropertySourcesPlaceholderConfigurer 的bean呢?让我们来看看源码吧.

PS:因为前面本人对 PropertySourcesPlaceholderConfigurer 理解有误,导致下面解释的模棱两可,因为spring是通过PropertySourcesPlaceholderConfigurer 内locations来查找属性文件,然后在根据注解将匹配的属性set进去,而下面的注释解释,是表示用注解可以做一些什么操作..

public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport

implements EnvironmentAware {

/**

* {@value} is the name given to the {@link PropertySource} for the set of

* {@linkplain #mergeProperties() merged properties} supplied to this configurer.

*/

public static final String LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME = "localProperties";

/**

* {@value} is the name given to the {@link PropertySource} that wraps the

* {@linkplain #setEnvironment environment} supplied to this configurer.

*/

public static final String ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME = "environmentProperties";

private MutablePropertySources propertySources;

private PropertySources appliedPropertySources;

private Environment environment;

下面代码省略.....

上面源码,并没能看出为什么一定要返回这个bean,那么我看就看看他的父类 PlaceholderConfigurerSupport 吧.以下是父类的源码

/**

* Abstract base class for property resource configurers that resolve placeholders

* in bean definition property values. Implementations pull values from a

* properties file or other {@linkplain org.springframework.core.env.PropertySource

* property source} into bean definitions.

*

*

The default placeholder syntax follows the Ant / Log4J / JSP EL style:

*

*

${...}

*

* Example XML bean definition:

*

*

{@code

*

*

*

*

*}

*

* Example properties file:

*

*

 driver=com.mysql.jdbc.Driver

* dbname=mysql:mydb

*

* Annotated bean definitions may take advantage of property replacement using

* the {@link org.springframework.beans.factory.annotation.Value @Value} annotation:

*

*

@Value("${person.age}")

*

* Implementations check simple property values, lists, maps, props, and bean names

* in bean references. Furthermore, placeholder values can also cross-reference

* other placeholders, like:

*

*

rootPath=myrootdir

*subPath=${rootPath}/subdir

*

* In contrast to {@link PropertyOverrideConfigurer}, subclasses of this type allow

* filling in of explicit placeholders in bean definitions.

*

*

If a configurer cannot resolve a placeholder, a {@link BeanDefinitionStoreException}

* will be thrown. If you want to check against multiple properties files, specify multiple

* resources via the {@link #setLocations locations} property. You can also define multiple

* configurers, each with its own placeholder syntax. Use {@link

* #ignoreUnresolvablePlaceholders} to intentionally suppress throwing an exception if a

* placeholder cannot be resolved.

*

*

Default property values can be defined globally for each configurer instance

* via the {@link #setProperties properties} property, or on a property-by-property basis

* using the default value separator which is {@code ":"} by default and

* customizable via {@link #setValueSeparator(String)}.

*

*

Example XML property with default value:

*

*

{@code

*

*}

*

* @author Chris Beams

* @author Juergen Hoeller

* @since 3.1

* @see PropertyPlaceholderConfigurer

* @see org.springframework.context.support.PropertySourcesPlaceholderConfigurer

*/

public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer

implements BeanNameAware, BeanFactoryAware {

/** Default placeholder prefix: {@value} */

public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

/** Default placeholder suffix: {@value} */

public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

/** Default value separator: {@value} */

public static final String DEFAULT_VALUE_SEPARATOR = ":";

/** Defaults to {@value #DEFAULT_PLACEHOLDER_PREFIX} */

protected String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;

/** Defaults to {@value #DEFAULT_PLACEHOLDER_SUFFIX} */

protected String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;

/** Defaults to {@value #DEFAULT_VALUE_SEPARATOR} */

protected String valueSeparator = DEFAULT_VALUE_SEPARATOR;

protected boolean ignoreUnresolvablePlaceholders = false;

protected String nullValue;

private BeanFactory beanFactory;

private String beanName;

类注释表示的是,该类所起的作用,替代了xml文件的哪些操作,我们只需要看下面定义的一个常量注解就能大概知道,为什么需要返回这么一个bean了.

类注释上有这么一句话:表示可以用带注释的bean,可以利用属性符号进行替换

* Annotated bean definitions may take advantage of property replacement using

* the {@link org.springframework.beans.factory.annotation.Value @Value} annotation:

*

*

@Value("${person.age}")

属性注释:

/** Default placeholder prefix: {@value} */

public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

/** Default placeholder suffix: {@value} */

public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

/** Default value separator: {@value} */

public static final String DEFAULT_VALUE_SEPARATOR = ":";

/** Defaults to {@value #DEFAULT_PLACEHOLDER_PREFIX} */

protected String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;

/** Defaults to {@value #DEFAULT_PLACEHOLDER_SUFFIX} */

protected String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;

/** Defaults to {@value #DEFAULT_VALUE_SEPARATOR} */

protected String valueSeparator = DEFAULT_VALUE_SEPARATOR;

protected boolean ignoreUnresolvablePlaceholders = false;

从上面注解可以发现,使用的 默认前缀是:  '${',  而后缀是:  '}' ,默认的分隔符是 ':', 但是set方法可以替换掉默认的分隔符,而 ignoreUnresolvablePlaceholders 默认为 false,表示会开启配置文件不存在,抛出异常的错误.

从上面就能看出这个bean所起的作用,就是将@propertySource注解的bean注入属性的作用,如果没有该bean,则不能解析${}符号.

下面是测试执行方法:

@Configuration

//扫描带有 @controller @service @Component 等spring注解的类注册为bean

@ComponentScan({"com.spring.annotation.annotationsAttribute"})

public class AnnotationsConfig {

public static void main(String[] args){

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationsConfig.class);

DemoAnnotation demoAnnotation = context.getBean(DemoAnnotation.class);

System.out.println(demoAnnotation.toString());

context.close();

}

}

打印结果为:

58d4e1d822c685365ec87f1443047f9f.png

这就表示,我们的注入成功了

使用 @PropertySource注解需要注意以下几个地方

使用注解需要将类申明被扫描为一个bean,可以使用@Component 注解

@PropertySource(value = "classpath:properties/config_userbean.properties",ignoreResourceNotFound = true) 表示注入配置文件,并且忽略配置文件不存在的异常

必须返回一个 PropertySourcesPlaceholderConfigurer 的bean,否则,会不能识别@Value("${userBean.name}") 注解中的 ${userBean.name}指向的value,而会注入${userBean.name}的字符串,返回 PropertySourcesPlaceholderConfigurer 的方法,使用@Bean注解,表示返回的是个bean

在spring 4.0以后,spring增加了@PropertySources 注解,下面是源码

/**

* Container annotation that aggregates several {@link PropertySource} annotations.

*

*

Can be used natively, declaring several nested {@link PropertySource} annotations.

* Can also be used in conjunction with Java 8's support for repeatable annotations,

* where {@link PropertySource} can simply be declared several times on the same

* {@linkplain ElementType#TYPE type}, implicitly generating this container annotation.

*

* @author Phillip Webb

* @since 4.0

* @see PropertySource

*/

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface PropertySources {

PropertySource[] value();

}

从源码的注释,可以看到自4.0以后,@PropertySources注解,可以使用多个@PropertySource注解,代码如下:

@PropertySources(

{

@PropertySource("classpath:properties/config_userbean.properties"),

@PropertySource("classpath:properties/config_mysql.properties")

}

)

有时候使用@PropertySource 注解会报 找不到这个注解的错误,但是spring确实是3.1以上版本,而且并不影响项目的使用,这样的话,可以使用@propertySources 注解嵌套@propertySource注解,这样就不会报错了

以上,均为本人测试而得出的结果,可能会有出入,或者错误,欢迎指正

欢迎转载,请注明出处跟作者,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值