女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

探討Spring框架中的屬性注入技術

OSC開源社區 ? 來源:OSCHINA 社區 ? 2023-06-14 09:37 ? 次閱讀

在本文中,我們深入探討了 Spring 框架中的屬性注入技術,包括 setter 注入、構造器注入、注解式屬性注入,以及使用 SpEL 表達式進行屬性注入。我們通過 XML 和注解兩種方式,詳細講解了如何進行屬性注入,并給出了完整的代碼示例。無論你是 Spring 新手,還是有一定經驗的開發者,本文都將幫助你理解并掌握 Spring 中的屬性注入技術。

1. setter 屬性注入

1.1 使用 XML 進行 setter 方法注入

我們在前面的文章中已經使用過 XML 進行 setter 方法的屬性注入了,下面讓我們再來回顧一下:


 
 
1.2 使用 @Bean 注解進行 setter 方法注入 我們在前面的文章中也學習過如何在 bean 創建時通過編程方式設置屬性:
@Bean
public User user() {
    User user = new User();
 user.setUsername("example-username-anno-setter");
 user.setAge(25);
 return user;
}
1.3 setter 方法注入完整代碼示例

使用 XML 進行 setter 方法注入

首先,我們需要創建一個 User 類,并在其中包含 username 和 age 兩個屬性,以及相應的 getter、setter 方法和構造器。

public class User {
 private String username;
 private Integer age;
 public User() {
 }
 // 為了節省篇幅,getter和setter方法省略......
    @Override
 public String toString() {
 return "User{username='" + username + "', age=" + age + "}";
 }
}

對于 XML 方式的 setter 注入和構造器注入,我們需要創建一個配置文件,比如叫 applicationContext.xml。


  
 
 
 
 

然后,我們需要創建一個 DemoApplication 類,使用 ApplicationContext 來加載配置文件并獲取 Bean:

import com.example.demo.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User userSetter = (User) context.getBean("userSetter");
 System.out.println(userSetter);
 }
}
運行結果如下:

1541745e-09dd-11ee-962d-dac502259ad0.png

使用 @Bean 注解進行 setter 方法注入

我們需要創建一個配置類,例如叫 AppConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
    @Bean
 public User userSetter() {
        User user = new User();
 user.setUsername("example-username-anno-setter");
 user.setAge(25);
 return user;
 }
}
使用 @Bean 注解來定義 Bean。每個 @Bean 方法對應于 XML 配置中的一個 元素。這個方法的名稱就是 Bean 的 id,方法的返回值就是 Bean 的類型 然后修改主程序,這里使用 AnnotationConfigApplicationContext 來創建 Spring 的應用上下文,并加載配置類。Spring 會自動從配置類中獲取所有的 Bean 定義,并創建相應的 Bean 實例。
package com.example.demo;
import com.example.demo.bean.User;
import com.example.demo.configuration.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        User userSetter = (User) context.getBean("userSetter");
 System.out.println(userSetter);
 }
}
運行結果如下

154f01dc-09dd-11ee-962d-dac502259ad0.png

注意:XML 配置方式已經相對陳舊,而且在 Spring Boot 項目中,主流的做法是使用注解和 Java 配置方式。對于 setter 注入,有時會引發循環依賴的問題。在 Spring 中,可以使用構造器注入來避免這種情況,這里了解即可。

2. 構造器注入

setter 注入是一種在對象被實例化之后(通過調用無參構造器創建實例)再通過 setter 方法注入依賴的方式。構造器注入則是在創建對象實例的時候就通過構造器參數來注入依賴。 為了演示構造器注入,我們需要給 User 添加一個全參數構造器:

public User(String username, Integer age) {
 this.username = username;
 this.age = age;
}
添加這個構造器后,Java 不再提供默認的無參構造器,這會導致我們之前的 標簽創建時失敗,因為它找不到默認的構造器。

2.1 使用 XML 進行構造器注入

我們可以在 標簽內部聲明一個子標簽:constructor-arg。它用于指定構造器的參數,來進行屬性注入。constructor-arg 標簽的編寫規則如下:


 
 
index 屬性表示構造函數參數的位置,它的值是一個非負整數,其中 0 表示第一個參數,1 表示第二個參數,以此類推。雖然 value 屬性的值總是一個字符串,但是 Spring 會嘗試將它轉換為構造函數參數所需的類型。例如構造函數的第二個參數是 int 類型,那么 Spring 會嘗試將字符串 "25" 轉換為整數 25。 使用 index 屬性來指定構造函數參數的位置在大多數情況下是可以的,但是如果構造函數的參數數量或者順序發生了改變,就可能會出錯。另外一種更為可靠的方式是使用 name 屬性來指定參數的名稱,如:

 
 
這樣無論參數的順序如何,只要參數名稱不變,就不會出錯。

2.2 使用 @Bean 注解進行構造器屬性注入

在注解驅動的 bean 注冊中,我們也可以直接使用編程方式賦值:

@Bean
public User user() {
 return new User("example-username-anno-constructor", 25);
}
2.3 構造器注入的完整代碼示例

使用 XML 進行構造器注入

首先,我們需要創建一個 User 類,并在其中包含 username 和 age 兩個屬性,以及相應的 getter、setter 方法和構造器。

public class User {
 private String username;
 private Integer age;
 public User() {
 }
 public User(String username, Integer age) {
 this.username = username;
 this.age = age;
 }
 // 為了節省篇幅,getter和setter方法省略......
    @Override
 public String toString() {
 return "User{username='" + username + "', age=" + age + "}";
 }
}

對于 XML 方式的構造器注入,我們需要創建一個配置文件,比如叫 applicationContext.xml,這里保留 setter 注入方便大家對比


  
  
 
 
 
 
  
 
 
 
 

然后,我們需要創建一個 DemoApplication 類,使用 ApplicationContext 來加載配置文件并獲取 Bean:

package com.example.demo;
import com.example.demo.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//        User userSetter = (User) context.getBean("userSetter");
//        System.out.println(userSetter);
        User userConstructor = (User) context.getBean("userConstructor");
 System.out.println(userConstructor);
 }
}
運行結果如下:

15621bdc-09dd-11ee-962d-dac502259ad0.png

使用 @Bean 注解進行構造器屬性注入

我們需要創建一個配置類,例如叫 AppConfig.java:

import com.example.demo.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
//    @Bean
//    public User userSetter() {
//        User user = new User();
//        user.setUsername("example-username-anno-setter");
//        user.setAge(25);
//        return user;
//    }
    @Bean
 public User userConstructor() {
 return new User("example-username-anno-constructor", 25);
 }
}

同樣,我們需要創建一個 DemoApplication 類,使用 AnnotationConfigApplicationContext 來加載配置類并獲取 Bean:

import com.example.demo.bean.User;
import com.example.demo.configuration.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//        User userSetter = (User) context.getBean("userSetter");
//        System.out.println(userSetter);
        User userConstructor = (User) context.getBean("userConstructor");
 System.out.println(userConstructor);
 }
}
運行結果:

156b97b6-09dd-11ee-962d-dac502259ad0.png

注意:如果在類中同時使用構造器注入和 setter 注入,需要注意它們注入的順序:先進行構造器注入,然后是 setter 注入。

3. 注解式屬性注入

上面我們已經說過注解式的 setter 和構造器注入。我們又是如何處理那些通過 @Component 掃描而注冊的 bean 的屬性的呢?我們來仔細說說這個問題,同時展示如何在 xml 中進行相同的操作。

3.1 @Value 注解式屬性注入的應用

首先,讓我們從最簡單的屬性注入方法:@Value 開始。創建一個新的 White 類,并聲明一些字段,但是這次我們不會設置 setter 方法:

@Component
public class White {
    @Value("white-value-annotation")
 private String title;
    @Value("1")
 private Integer rank;
    @Override
 public String toString() {
 return "White{" + "title='" + title + ''' + ", rank=" + rank + '}';
 }
}

要實現注解式屬性注入,我們可以直接在需要注入的字段上添加 @Value 注解:

@Value("white-value-annotation")
private String title;
@Value("1")
private Integer rank;

要注意的是,如果使用 @Value 注解來注入一個不存在的屬性,那么應用程序會在啟動時拋出異常。

然后,我們將通過組件掃描方式將這個 White 類掃描到 IOC 容器中,并將其取出并打印:

public class DemoApplication {
 public static void main(String[] args) throws Exception {
 ApplicationContext ctx = new AnnotationConfigApplicationContext(White.class);
        White white = ctx.getBean(White.class);
 System.out.println("Injected value : " + white);
 }
}

運行 main 方法會看到 White 的字段已經成功注入:

Injected value : White{
   title='white-value-annotation', rank=1}
3.2 引入外部配置文件 @PropertySource 如果我們需要在 Spring 中使用 properties 文件,我們應該怎么辦呢?Spring 考慮到了這一點,并擴展了一個用于導入外部配置文件的注解:@PropertySource。

創建 Bean 和配置文件

創建一個新的 Blue 類,其結構與 White 類完全相同。然后在項目的 resources 目錄下創建一個新的 blue.properties 文件,用于存儲 Blue 類的屬性配置:

blue.title=blue-value-properties
blue.rank=2

引入配置文件

使用 @PropertySource 注解將 properties 文件導入到配置類:

@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:blue.properties")
public class InjectValueConfiguration {
}
這個 blue.properties 文件是一個鍵值對的列表,Spring 將這些鍵值對加載到 Environment 中,我們可以通過 @Value 注解或者 Environment 類的方法來獲取這些屬性值。 @Value 注解和 Environment 類都可以用于讀取 Spring 上下文中的屬性值。這些屬性值可能來自于多個不同的源,包括但不限于:

Spring Boot 的默認配置文件(application.properties 或 application.yml)。

通過 @PropertySource 注解加載的屬性文件。

系統環境變量。

Java 系統屬性(可以通過 -D 命令行參數設置)。

如果你想通過 @Value 注解來獲取屬性值,如下:

@Component
public class BlueConfig {
    @Value("${blue.title}")
 private String title;
    @Value("${blue.rank}")
 private int rank;
 // getters and setters...
}

在 Spring 應用中使用 @PropertySource 注解來加載一個 .properties 文件時,這個文件中的所有配置項都會被讀取,并存儲在一個內部的 Map 結構中。這個 Map 的鍵是配置項的名稱,值是配置項的值。Spring 中的一些內置配置項也會被添加到這個 Map 中。

當我們使用 ${...}`占位符語法來引用一個配置項時,`Spring`會查找這個`Map`,取出與占位符名稱相應的配置項的值。例如有一個配置項`blue.title=blue-value-properties`,我們可以在代碼中使用`${blue.title} 占位符來引用這個配置項的值。

如果想通過 Environment 類的方法來獲取屬性值,可以像下面這樣做:

@Component
public class SomeComponent {
    @Autowired
 private Environment env;
 public void someMethod() {
        String title = env.getProperty("blue.title");
        int rank = Integer.parseInt(env.getProperty("blue.rank"));
 // ...
 }
}
在上述代碼中,Environment 類的 getProperty 方法用于獲取屬性值。注意,getProperty 方法返回的是 String,所以如果屬性是非字符串類型(如 int),則需要將獲取的屬性值轉換為適當的類型。 注意:@PropertySource無法加載YAML格式的文件,只能加載 properties 格式的文件。如果需要加載 YAML 格式的文件,而且使用的是 Spring Boot 框架,那么可以使用 @ConfigurationProperties 或 @Value 注解。例如以下的 YAML 文件: application.yml
appTest:
  name: MyApp
  version: 1.0.0

可以使用 @ConfigurationProperties 來加載這些屬性:

@Configuration
@ConfigurationProperties(prefix = "appTest")
public class AppConfig {
 private String name;
 private String version;
 // getters and setters...
}
@ConfigurationProperties 注解主要用于指定配置屬性的前綴,@ConfigurationProperties 注解本身并不直接指定配置文件的位置, 而是由 Spring Boot 的自動配置機制處理的。 這樣,name 字段就會被自動綁定到 appTest.name 配置屬性,version 字段就會被自動綁定到 appTest.version 配置屬性。

默認情況下,Spring Boot 會在啟動時自動加載 src/main/resources 目錄下的 application.properties 或 application.yml 文件。我們可以通過設置 spring.config.name 和 spring.config.location 屬性來改變默認的配置文件名或位置。 注意:@ConfigurationProperties 注解需要配合 @EnableConfigurationProperties 注解或 @Configuration 注解使用,以確保 Spring 能夠發現并處理這些注解。

或者,你也可以使用 @Value 注解來加載這些屬性:
@Component
public class AppConfig {
    @Value("${appTest.name}")
 private String name;
    @Value("${appTest.version}")
 private String version;
 // getters and setters...
}

Blue 類的屬性注入

對于 properties 類型的屬性,我們這里選擇 @Value 注解和占位符來注入屬性:

@Value("${blue.title}")
private String title;
@Value("${blue.rank}")
private Integer rank;
如果你熟悉 jsp 的 el 表達式,會發現這和它非常相似!

測試啟動類

修改啟動類,將配置類引入,然后取出并打印 Blue:

public static void main(String[] args) throws Exception {
 ApplicationContext ctx = new AnnotationConfigApplicationContext(InjectValueConfiguration.class);
    Blue blue = ctx.getBean(Blue.class);
 System.out.println("Properties value : " + blue);
}

運行 main 方法會看到控制臺已經成功打印出了配置文件的屬性:

Properties value : Blue{
   title='blue-value-properties', rank=2}
3.3 在 XML 中引入外部配置文件 在 xml 中,我們可以和 @Value 相同的方式使用占位符:


  
 
 
 
 
 
3.4 注解式屬性注入完整代碼示例

@Value 注解式屬性注入的應用

創建 White 類:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class White {
    @Value("white-value-annotation")
 private String title;
    @Value("1")
 private Integer rank;
    @Override
 public String toString() {
 return "White{" + "title='" + title + ''' + ", rank=" + rank + '}';
 }
}

創建啟動類 InjectValueAnnotationApplication:

package com.example.demo;
import com.example.demo.bean.White;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
 public static void main(String[] args) throws Exception {
 ApplicationContext ctx = new AnnotationConfigApplicationContext(White.class);
        White white = ctx.getBean(White.class);
 System.out.println("Injected value : " + white);
 }
}
運行結果如下:

1576c848-09dd-11ee-962d-dac502259ad0.png

引入外部配置文件 @PropertySource

創建 Blue 類和配置文件,沒有 setter 和 getter 方法:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Blue {
    @Value("${blue.title}")
 private String title;
    @Value("${blue.rank}")
 private Integer rank;
    @Override
 public String toString() {
 return "Blue{" + "title='" + title + ''' + ", rank=" + rank + '}';
 }
}

resources 目錄下的 blue.properties 文件:

blue.title=blue-value-properties
blue.rank=2

創建配置類 InjectValueConfiguration:

package com.example.demo.configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:blue.properties")
public class InjectValueConfiguration {
}

修改啟動類,引入配置類:

package com.example.demo;
import com.example.demo.bean.Blue;
import com.example.demo.configuration.InjectValueConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
 public static void main(String[] args) throws Exception {
 ApplicationContext ctx = new AnnotationConfigApplicationContext(InjectValueConfiguration.class);
        Blue blue = ctx.getBean(Blue.class);
 System.out.println("Properties value : " + blue);
 }
}
運行結果如下:

158ce966-09dd-11ee-962d-dac502259ad0.png

在 xml 中引入外部配置文件

在使用 XML 配置的情況下,我們需要創建一個 XML 文件來替代 InjectValueConfiguration 類,我們可以先注釋掉 InjectValueConfiguration 類的所有內容 下面是相應的 XML 文件內容:



  
 
 
 
 
 
在這里我們使用了 context:property-placeholder 標簽來導入外部的 properties 文件,然后使用 ${...} 占位符語法來引用配置文件中的屬性值。這樣無論是選擇用注解方式還是 XML 方式,都可以方便地在 Spring 中使用外部配置文件。 這里還需要修改下 Blue 類,因為通過 XML 方法注入屬性需要提供相應的 setter 方法,修改后的 Blue 類如下:
package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Blue {
    @Value("${blue.title}")
 private String title;
    @Value("${blue.rank}")
 private Integer rank;
 public String getTitle() {
 return title;
 }
 public void setTitle(String title) {
 this.title = title;
 }
 public Integer getRank() {
 return rank;
 }
 public void setRank(Integer rank) {
 this.rank = rank;
 }
    @Override
 public String toString() {
 return "Blue{" + "title='" + title + ''' + ", rank=" + rank + '}';
 }
}

然后,我們需要修改啟動類,使用 XmlApplicationContext 代替 AnnotationConfigApplicationContext:

package com.example.demo;
import com.example.demo.bean.Blue;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@ComponentScan("com.example")
public class DemoApplication {
 public static void main(String[] args) throws Exception {
 ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:injectValueContext.xml");
        Blue blue = ctx.getBean(Blue.class);
 System.out.println("Properties value : " + blue);
 }
}
運行結果如下:

1596286e-09dd-11ee-962d-dac502259ad0.png

4. SpEL 表達式

當我們談到屬性注入的時候,我們可能會遇到一些復雜的需求,例如我們需要引用另一個 Bean 的屬性,或者我們需要動態處理某個屬性值。這種需求無法通過使用 ${} 的占位符方式實現,我們需要一個更強大的工具:SpEL 表達式。 Spring Expression Language(SpEL)是從 Spring 框架 3.0 開始支持的強大工具。

SpEL 不僅是 Spring 框架的重要組成部分,也可以獨立使用。它的功能豐富,包括調用屬性值、屬性參數、方法調用、數組存儲以及邏輯計算等。它與開源項目 OGNL(Object-Graph Navigation Language)相似,但 SpEL 是 Spring 框架推出的,并默認內嵌在 Spring 框架中。

4.1 使用 @Value 注解和 SpEL 表達式實現屬性注入

SpEL 的表達式用 #{} 表示,花括號中就是我們要編寫的表達式。 我們創建一個 Bean,命名為 Azure,同樣地,我們聲明屬性 name 和 priority,并提供 getter 和 setter 方法以及 toString () 方法。然后我們使用 @Component 注解標注它。 使用 @Value 配合 SpEL 完成屬性注入,如下:

@Component
public class Azure {
    @Value("#{'spel-for-azure'}")
 private String name;
    @Value("#{10}")
 private Integer priority;
}

我們修改啟動類,從 IOC 容器中獲取 Azure 并打印,可以看到屬性被成功注入:

Azure{
   name='spel-for-azure', priority=10}

SpEL 的功能遠不止這些,它還可以獲取 IOC 容器中其他 Bean 的屬性,讓我們來展示一下。

我們已經注冊了 Azure Bean,現在我們再創建一個 Bean,命名為 Emerald。我們按照上述方法對字段和方法進行聲明,然后使用 @Component 注解標注。

我們希望 name 屬性直接復制 Azure 的 name 屬性,而 priority 屬性則希望比 Azure 的 priority 屬性大 1,我們可以這樣編寫:

@Component
public class Emerald {
    @Value("#{'copy of ' + azure.name}")
 private String name;
    @Value("#{azure.priority + 1}")
 private Integer priority;
}
在 Spring 的 SpEL 中可以通過 bean 的名稱訪問到對應的 bean,并通過。操作符訪問 bean 的屬性。在這個例子中,azure 就是一個 bean 的名稱,它對應的 bean 就是 Azure 類的實例。所以,azure.name 就是訪問 Azure 類實例的 name 屬性。 如果你在一個不涉及 Spring 的環境中使用 SpEL,這個特性是不會生效的。這是因為這個特性依賴于 Spring 的 IoC 容器。 我們修改啟動類,測試運行,可以看到 Azure 的屬性已經成功被復制:
use spel bean property : Emerald{
   name='copy of spel-for-azure', priority=11}

SpEL 表達式不僅可以引用對象的屬性,還可以直接引用類的常量,以及調用對象的方法。下面我們通過示例進行演示。

我們新建一個 Bean,命名為 Ivory。我們按照上述方法初始化屬性、toString () 方法、注解。

假設我們有一個需求,讓 name 取 azure 屬性的前 3 個字符,priority 取 Integer 的最大值。那么我們可以使用 SpEL 這樣寫:

@Component
public class Ivory {
    @Value("#{azure.name.substring(0, 3)}")
 private String name;
    @Value("#{T(java.lang.Integer).MAX_VALUE}")
 private Integer priority;
}

注意,直接引用類的屬性,需要在類的全限定名外面使用 T () 包圍。

我們修改啟動類,測試運行,可以看到 Ivory 的屬性已經是處理之后的值:

use spel methods : Ivory{
   name='spe', priority=2147483647}
4.2 在 XML 中使用 SpEL 表達式實現屬性注入:

 
 
學習 SpEL 表達式不需要花費大量的精力,掌握基礎的使用方法即可。 4.3 SpEL 表達式屬性注入完整代碼示例

使用 @Value 注解和 SpEL 表達式實現屬性注入

創建三個 SpEL 表達式屬性注入的 Bean:Azure.java、Emerald.java 和 Ivory.java。 Azure.java:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Azure {
    @Value("#{'spel-for-azure'}")
 private String name;
    @Value("#{10}")
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Azure{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}
Emerald.java:
package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Emerald {
    @Value("#{'copy of ' + azure.name}")
 private String name;
    @Value("#{azure.priority + 1}")
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Emerald{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}

Ivory.java:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Ivory {
    @Value("#{azure.name.substring(0, 3)}")
 private String name;
    @Value("#{T(java.lang.Integer).MAX_VALUE}")
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Ivory{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}

MyBean.java

@Component
public class MyBean {
    @Autowired
 private Azure azure;
    @Autowired
 private Emerald emerald;
    @Autowired
 private Ivory ivory;
 public void init() {
 System.out.println(azure);
 System.out.println(emerald);
 System.out.println(ivory);
 }
}
MyBean 是一個用于展示如何在 Spring 中通過 SpEL 表達式來注入屬性的類,它聚合了三個對象 Azure, Emerald 和 Ivory,并通過 Spring 的依賴注入機制將這三個對象注入到了 MyBean 類的實例中 主程序 DemoApplication
@SpringBootApplication
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
 MyBean myBean = applicationContext.getBean(MyBean.class);
 myBean.init();
 }
}
運行結果:

15a2419e-09dd-11ee-962d-dac502259ad0.png

在 XML 中使用 SpEL 表達式實現屬性注入

對于 XML 配置,Spring 還支持在 bean 定義中使用 SpEL。 首先,需要創建一個 Spring XML 配置文件,我們將其命名為 app-config.xml:



 
 
 
 
 
 
 
 
 
 
 
 
 
注意:在 XML 中使用 SpEL 需要使用 #{},而不是 ${}。 然后修改這 3 個 Bean,如果是使用 XML 來配置 Spring 的 Bean 的話,那么在 Java 類中就不需要使用 @Component 注解了。因為 XML 配置文件已經明確地告訴 Spring 這些類是 Spring Bean。 同樣的,如果在 XML 文件中定義了 Bean 的屬性值,那么在 Java 類中就不需要使用 @Value 注解來注入這些值了。因為 XML 配置文件已經明確地為這些屬性賦了值。 Azure.java
package com.example.demo.bean;
public class Azure {
 private String name;
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Azure{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}
Emerald.java
package com.example.demo.bean;
public class Emerald {
 private String name;
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Emerald{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}

Ivory.java

package com.example.demo.bean;
public class Ivory {
 private String name;
 private Integer priority;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getPriority() {
 return priority;
 }
 public void setPriority(Integer priority) {
 this.priority = priority;
 }
    @Override
 public String toString() {
 return "Ivory{" +
 "name='" + name + ''' +
 ", priority=" + priority +
 '}';
 }
}
然后需要在主程序中導入這個 XML 配置文件,這可以通過在主程序中添加 @ImportResource 注解實現:
package com.example.demo;
import com.example.demo.bean.MyBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("classpath:app-config.xml")
public class DemoApplication {
 public static void main(String[] args) {
 ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
 MyBean myBean = applicationContext.getBean(MyBean.class);
 myBean.init();
 }
}
這樣就可以在 Spring 的 XML 配置文件中使用 SpEL 了。 運行結果如下:

15b9389a-09dd-11ee-962d-dac502259ad0.png






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7623

    瀏覽量

    166213
  • JAVA語言
    +關注

    關注

    0

    文章

    138

    瀏覽量

    20500
  • XML技術
    +關注

    關注

    0

    文章

    15

    瀏覽量

    6096
  • YAML
    +關注

    關注

    0

    文章

    21

    瀏覽量

    2429

原文標題:揭秘Spring依賴注入和SpEL表達式

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    java spring教程

    Spring核心概念介紹控制反轉(IOC)依賴注入(DI)集合對象注入等Bean的管理BeanFactoryApplicationContextSpring 在web的使用
    發表于 09-11 11:09

    什么是java spring

    。在SSH項目中管理事務以及對象的注入Spring是非侵入式的:基于Spring開發的系統的對象一般不依賴于Spring的類。組成
    發表于 09-11 11:16

    怎么閱讀Spring源碼

    封裝,很有可能在讀源碼的過程掉到各種細節里出不來,所以讀這種源碼要事無巨細,理解原理即可。基本原理其實就是通過反射解析類及其類的各種信息,包括構造器、方法及其參數,屬性。然后將其封裝成bean定義
    發表于 05-04 15:21

    三大框架Spring

    ;出現了Spring,可以自動創建需要被調用的對象以及進行屬性注入,也可以維護這些bean(具體的java類)之間的關系;
    發表于 05-27 07:21

    Spring框架的設計理念

    Spring作為現在最優秀的框架之一,已被廣泛的使用,51CTO也曾經針對Spring框架的hqC應用做過報道。本文將從另外一個視角試圖剖
    發表于 07-15 08:17

    一文解析Spring框架

    Spring框架詳解 - 03
    發表于 06-17 17:15

    Spring筆記分享

    ; 可以管理所有的組件(類)Spring的優良特性1) 非侵入式:基于Spring開發的應用的對象可以不依賴于Spring的API2) 依賴注入
    發表于 11-04 07:51

    MVC框架實例—Spring MVC配置

    本文旨在讓您在使用Spring MVC框架配置完成日常工作的時候更加輕松。根據Spring MVC框架配置,為基于本技術開發的項目提供一系列
    發表于 12-14 17:37 ?3240次閱讀

    Spring集成Acegi安全框架在J2EE的應用

    Acegi是一個基于Spring的安全框架探討Spring框架集成Acegi的方法,即在Spring
    發表于 05-07 14:11 ?19次下載

    spring mvc框架介紹

    。使用 Spring 可插入的 MVC 架構,可以選擇是使用內置的 Spring Web 框架還是 Struts 這樣的 Web 框架。通過策略接口,
    發表于 11-17 16:28 ?2460次閱讀
    <b class='flag-5'>spring</b> mvc<b class='flag-5'>框架</b>介紹

    spring框架定時器使用與配置

    Spring是于2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson創建。簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架
    發表于 01-26 17:11 ?1879次閱讀

    Spring認證」Spring 框架概述

    Spring 框架是一個開源的 Java 平臺。它最初由 Rod Johnson 編寫,并于 2003 年 6 月在 Apache 2.0 許可下首次發布。 Spring Framework 的核心
    的頭像 發表于 08-12 15:07 ?822次閱讀
    「<b class='flag-5'>Spring</b>認證」<b class='flag-5'>Spring</b> <b class='flag-5'>框架</b>概述

    Spring依賴注入的方式

    Spring 是一個開源的輕量級框架,可以用于構建企業級應用程序。其最重要的特性之一是依賴注入(Dependency Injection,DI),這是一種設計模式,它可以幫助我們解耦代碼、提高
    的頭像 發表于 11-22 15:12 ?694次閱讀

    Spring依賴注入的四種方式

    Spring框架,依賴注入是一種核心的概念和機制。通過依賴注入,我們可以讓對象之間的依賴關系更加松散,并且能夠方便地進行單元測試和模塊化
    的頭像 發表于 12-03 15:11 ?2365次閱讀

    Spring Cloud Gateway網關框架

    Spring Cloud Gateway網關框架 本軟件微服務架構采用Spring Cloud Gateway網關控制框架
    的頭像 發表于 08-22 09:58 ?658次閱讀
    <b class='flag-5'>Spring</b> Cloud Gateway網關<b class='flag-5'>框架</b>