經過@Value將外部的值動態注入到Bean中,使用的狀況有:php
輔助代碼html
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "st")//對student進行實例化操做
public class Student {
@Value("悟空")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
複製代碼
測試@Value的代碼java
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
@Component
public class SimpleObject {
@Value("注入普通字符串")
private String normal;
//關於屬性的KEY能夠查看System類說明
@Value("#{systemProperties['java.version']}")//-->使用了SpEL表達式
private String systemPropertiesName; // 注入操做系統屬性
@Value("#{T(java.lang.Math).random()*80}")//獲取隨機數
private double randomNumber; //注入表達式結果
@Value("#{1+2}")
private double sum; //注入表達式結果 1+2的求和
@Value("classpath:os.yaml")
private Resource resourceFile; // 注入文件資源
@Value("http://www.baidu.com")
private Resource testUrl; // 注入URL資源
@Value("#{st.name}")
private String studentName;
//省略getter和setter方法
@Override
public String toString() {
return "SimpleObject{" +
"normal='" + normal + '\'' +
", systemPropertiesName='" + systemPropertiesName + '\'' +
", randomNumber=" + randomNumber +
", sum=" + sum +
", resourceFile=" + resourceFile +
", testUrl=" + testUrl +
", studentName='" + studentName + '\'' +
'}';
}
}
複製代碼
Spring的測試代碼spring
package com.hannpang;
import com.hannpang.model.SimpleObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private SimpleObject so;
@Test
public void contextLoads() {
System.out.println(so);
}
}
複製代碼
運行結果爲:SimpleObject{normal='注入普通字符串', systemPropertiesName='1.8.0_172', randomNumber=56.631954541947266, sum=3.0, resourceFile=class path resource [os.yaml], testUrl=URL [http://www.baidu.com], studentName='悟空'}
複製代碼
經過@Value將外部配置文件的值動態注入到Bean中。配置文件主要有兩類:springboot
在application.properties中加入以下測試代碼app
app.name=一步教育
複製代碼
在resources下面新建第一個屬性文件config.properties
內容以下dom
book.name=西遊記
anotherfile.configinject=system
複製代碼
在resources下面新建第二個屬性文件config_system.properties
內容以下ide
個人目的是想system的值使用第一個屬性文件中定義的值測試
book.name.author=吳承恩
複製代碼
下面經過@Value(「${app.name}」)
語法將屬性文件的值注入bean屬性值,詳細代碼見:ui
package com.hannpang.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:config.properties","classpath:config_${anotherfile.configinject}.properties"})
public class LoadPropsTest {
@Value("${app.name}")
private String appName; // 這裏的值來自application.properties,spring boot啓動時默認加載此文件
@Value("${book.name}")
private String bookName; // 注入第一個配置外部文件屬性
@Value("${book.name.author}")
private String author; // 注入第二個配置外部文件屬性
@Autowired
private Environment env; // 注入環境變量對象,存儲注入的屬性值
//省略getter和setter方法
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("bookName=").append(bookName).append("\r\n")
.append("author=").append(author).append("\r\n")
.append("appName=").append(appName).append("\r\n")
.append("env=").append(env).append("\r\n")
// 從eniroment中獲取屬性值
.append("env=").append(env.getProperty("book.name.author")).append("\r\n");
return sb.toString();
}
}
複製代碼
測試代碼
package com.hannpang;
import com.hannpang.model.SimpleObject;
import com.hannpang.test.LoadPropsTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private LoadPropsTest lpt;
@Test
public void loadPropertiesTest() {
System.out.println(lpt);
}
}
複製代碼
運行結果爲:
bookName=西遊記
author=吳承恩
appName=一步教育
env=StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, MapPropertySource {name='Inlined Test Properties'}, MapPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}, ResourcePropertySource {name='class path resource [config_system.properties]'}, ResourcePropertySource {name='class path resource [config.properties]'}]}
env=吳承恩
複製代碼
#{...}和${...}
的區別演示${…}
的用法{}裏面的內容必須符合SpEL表達式,經過@Value(「${app.name}」)
能夠獲取屬性文件中對應的值,可是若是屬性文件中沒有這個屬性,則會報錯。能夠經過賦予默認值解決這個問題,如@Value("${app.name:胖先森}")
部分代碼
// 若是屬性文件沒有app.name,則會報錯
// @Value("${app.name}")
// private String name;
// 使用app.name設置值,若是不存在則使用默認值
@Value("${app.name:胖先森}")
private String name;
複製代碼
#{...}
的用法部分代碼直接演示
// SpEL:調用字符串Hello World的concat方法
@Value("#{'Hello World'.concat('!')}")
private String helloWorld;
// SpEL: 調用字符串的getBytes方法,而後調用length屬性
@Value("#{'Hello World'.bytes.length}")
private String helloWorldbytes;
複製代碼
#{...}
和${...}
混合使用${...}和#{...}
能夠混合使用,以下文代碼執行順序:經過${server.name}從屬性文件中獲取值並進行替換,而後就變成了 執行SpEL表達式{‘server1,server2,server3’.split(‘,’)}。
// SpEL: 傳入一個字符串,根據","切分後插入列表中, #{}和${}配置使用(注意單引號,注意不能反過來${}在外面,#{}在裏面)
@Value("#{'${server.name}'.split(',')}")
private List<String> servers;
複製代碼
在上文中在#{}外面,${}在裏面
能夠執行成功,那麼反過來是否能夠呢${}在外面,#{}在裏面
,如代碼
// SpEL: 注意不能反過來${}在外面,#{}在裏面,這個會執行失敗
@Value("${#{'HelloWorld'.concat('_')}}")
private List<String> servers2;
複製代碼
答案是不能。
由於spring執行${}是時機要早於#{}。
在本例中,Spring會嘗試從屬性中查找#{‘HelloWorld’.concat(‘_’)},那麼確定找到,由上文已知若是找不到,而後報錯。因此${}在外面,#{}在裏面是非法操做
複製代碼
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的屬性 | 一個個指定 |
鬆散綁定(鬆散語法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303數據校驗 | 支持 | 不支持 |
複雜類型封裝 | 支持 | 不支持 |
配置文件yml仍是properties他們都能獲取到值;
若是說,咱們只是在某個業務邏輯中須要獲取一下配置文件中的某項值,使用@Value;
若是說,咱們專門編寫了一個javaBean來和配置文件進行映射,咱們就直接使用@ConfigurationProperties;
關於數據校驗的部分代碼
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
//lastName必須是郵箱格式
@Email
private String lastName;
複製代碼
@ImportResource
引入配置文件不推薦的使用方式
Spring Boot裏面沒有Spring的配置文件,咱們本身編寫的配置文件,也不能自動識別;
想讓Spring的配置文件生效,加載進來;@ImportResource標註在一個配置類上
@ImportResource(locations = {"classpath:beans.xml"})
導入Spring的配置文件讓其生效
複製代碼
編寫配置文件信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.hanpang.springboot.service.HelloService"></bean>
</beans>
複製代碼
大概瞭解就好,咱們基本上不使用這種方式
@Configuration
註解SpringBoot推薦給容器中添加組件的方式;推薦使用全註解的方式
一、配置類@Configuration
做用於類上,至關於一個xml配置文件
二、使用@Bean
給容器中添加組件,做用於方法上
/** * @Configuration:指明當前類是一個配置類;就是來替代以前的Spring配置文件 * * 在配置文件中用<bean><bean/>標籤添加組件 * <bean id="helloService" class="com.hanpang.springboot.service.HelloService"></bean> */
@Configuration
public class MyAppConfig {
//將方法的返回值添加到容器中;容器中這個組件默認的id就是方法名
@Bean
public HelloService helloService02(){
System.out.println("配置類@Bean給容器中添加組件了...");
return new HelloService();
}
}
複製代碼
使用Bean注入太麻煩,咱們更加喜歡使用掃描的方式
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.wx.dao.IUserDao;
import com.wx.dao.UserDaoImpl;
//經過該註解來代表該類是一個Spring的配置,至關於一個傳統的ApplicationContext.xml
@Configuration
//至關於配置文件裏面的<context:component-scan/>標籤,掃描這些包下面的類的註解
@ComponentScan(basePackages="com.hanpang.dao,com.hanpang.service")
public class SpringConfig {
// 經過該註解來代表是一個Bean對象,至關於xml中的<bean>
//bean的id值默認是方法名userDao
/* @Bean public HelloService helloService02(){ System.out.println("配置類@Bean給容器中添加組件了..."); return new HelloService(); } */
}
複製代碼
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
複製代碼