配置文件,我以兩種為例,一種是引入Spring的XML文件,另外一種是.properties的鍵值對文件;
一。引入Spring XML的注解是@ImportResource
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface ImportResource
@ImportResource有三個屬性,value、locations、reader,准確來說是兩個,locations和value屬性是一樣的,都是接受字符串數組,代表導入文件的位置;reader是代表Spring解析文件的類,Spring支持XML或者groovy方式的文件解析,默認的XML解析的reader對象為XmlBeanDefinitionReader的doLoadBeanDefinitions方法;
用法就像下面這樣:當然如果不是Spring注解的容器AnnotationConfigApplicationContext,同樣可以使用@ImportResource注解,只要開啟了注解掃描,並且標注的類已經被Spring管理到了(比如標注了注解@Component等 或者 XML中定義過該bean)
@ImportResource(locations= {"com/lvbinbin/pack1/spring.xml"}) public class AppConfig { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); String[] names = ac.getBeanDefinitionNames(); for (String string : names) { System.out.println(string+" , "+ac.getBean(string)); } } }
簡而言之,使用@ImportResource生效兩個條件,一是開啟包掃描 ,當然別的配置也有這種功能,只要滿足注冊了ConfigurationClassPostProcessor 這個BPP對象,如果不知道有沒有這個bean,用上面的方式查看容器中所有的bean有沒有這個bean就能知道;
二是@ImportResource標注的類已經是個bean,被Spring管理到了,上面輸出所有bean的方式就可以查看;
二。引入properties文件的注解有一種是 @PropertySource
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(PropertySources.class) public @interface PropertySource
先來介紹@PropertySource的用法
jdbc.properties
jdbcDriver=com.mysql.jdbc.Driver userName=root userName_zh=呂彬彬 userName_en=lvbinbin
配置類 當然這個注解是標注在類上的,但是不一定要只能標注在@Configuration注解的類上,只要被Spring管理到的Bean都是可以標注的,然后使用@Value("${}")的方式注入的; 只要PropertySource的文件引入一次,該Spring容器中bean都可以使用@Value來設置屬性;
@Configuration @PropertySource(value= {"pack5/jdbc.properties"}) public class ConfigA { @Value("${jdbcDriver}") private String jdbcName; @Value("${userName_zh}") private String userName; public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ConfigA.class); System.out.println(ac.getBean(ConfigA.class).jdbcName); System.out.println(ac.getBean(ConfigA.class).userName); MutablePropertySources mps = ac.getEnvironment().getPropertySources(); mps.forEach(ps->{System.out.println(ps.getName());}); } }
查看結果: 也驗證了這種方式可以注入屬性; 下面三行輸出就是environment對象中的propertySources集合里已經有的propertySource; 其中最后一行就是這個jdbc.propertySource的name,這是Spring默認生成規則生成的;如果不滿意,可以按照下面的方式來生成自定義;
修改注解@PropertySource里的name屬性:
@PropertySource(value= {"pack5/jdbc.properties"},name="mysqlJdbcProperties")
測試結果就顯示成為這樣:
這樣@PropertySource的屬性說明: 1. name就是該配置文件對應的properySource的name值,你要說用處嘛? 可以通過如下方式指定propertySource的name值來獲取配置文件中的鍵值對;
String res = (String) ac.getEnvironment().getPropertySources().get("mysqlJdbcProperties").getProperty("userName_zh");
2. value就是配置文件的位置,字符串數組,支持Spring的多種資源寫法,classpath、file等;
3. ignoreResourceNotFound 屬性 默認是false,當配置文件不存在的時候,就會拋出異常;true代表沒有該文件也沒有問題;建議默認即可,這樣缺少配置文件時候能夠發現問題所在;因為${}這種解析方式 比如鍵 值不存在,會原樣的字符串返回;
4. encoding 屬性就是編碼,默認是UTF-8;具體使用效果我也看不出來,如果引入properties文件亂碼了,不妨試試修改該屬性;
此外,SpringEl表達式也是可以注入屬性的,簡單介紹下使用方式:其中 environment 是Spring容器中的環境對象的名字,后面直接跟需要的屬性,就會遍歷PropertySources對象去尋找;
@Value("#{environment['userName_en']}") private String userNameEn;
查看輸出
lvbinbin
查看Spring日志,證明了這一點;不過我覺得還是 ${}更容易理解一點