spring(一)依赖注入与 SPEL
Spring之依賴注入與 SPEL
- 一、控制反轉與依賴注入
- 二、helloworld
- 三、構造注入
- 四、級聯注入
- 五、單例與多例
- 六、工廠方法創建 Bean
- 七、包掃描管理 bean
- 八、SPEL與資源調用
- 九、對象屬性拷貝(自)
- 十、單元測試
- 十一、spring與 mybatis 整合
一、控制反轉與依賴注入
IOC(Inversion of Control) 控制反轉
??首先想說說 IOC(Inversion of Control)控制反轉。這是 spring 的核心,貫穿始終。所謂 IOC,對于 spring 框架來說,就是由 spring 來負責控制對象的生命周期和對象間的關系。程序開發中,在一個對象中如果要使用另外的對象,就必須得到它常見的兩種方式是自己 new 一個該對象,或者從 JNDI(Java 命名與目錄接口(Java Naming and Directory Interface)中查詢一個,使用完之后還要將對象銷毀(比如 Connection 等),對象始終會和其他的接口或類藕合起來。
??Spring 所倡導的開發方式是這樣,所有的類都會在 spring 容器中登記,告訴 spring 該類是做什么用,需要依賴其他什么類,然后 spring 會在系統運行到適當的時候,把需要的類對象主動注入到標記的位置,同時也把該類交給其他需要的地方。所有的類的創建、銷毀都由 spring 來控制,也就是說控制對象生存周期的不再是引用它的對象,而是 spring。對于某個具體的對象而言,以前是它控制其他對象,現在是所有對象都被 spring 控制,所以這叫控制反轉。
DI(Dependency Injection) 依賴注入
??IOC 的一個重點是在系統運行中,動態的向某個對象提供它所需要的其他對象。這一點是通過 DI(Dependency Injection,依賴注入)來實現的。比如對象A 需要操作數據庫,以前我們總是要在 A 中自己編寫代碼來獲得一個 Connection 對象,有了 spring 我們就只需要告訴 spring,A 中需要一個 Connection,至于這個 Connection 怎么構造,何時構造,A 不需要知道。在系統運行時,spring 會在適當的時候制造一個 Connection,然后像打針一樣,注射到 A 當中,這樣就完成了對各個對象之間關系的控制。A 需要依賴 Connection 才能正常運行,而這個 Connection 是由 spring 注入到 A 中的,依賴注入的名字就這么來的。那么 DI 是如何實現的呢? Java 1.3 之后一個重要特征是反射(reflection),它允許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring 就是通過反射來實現注入的。
二、helloworld
??使用 maven 創建一個 web 項目,并添加 spring 上下文容器依賴。該依賴 spring 依賴其他幾個 spring 常用依賴如:spring-aop、spring-beans、、spring-core、spring-expression 等。
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.12.RELEASE</version> </dependency>maven 會自動幫我們解決依賴之間的關聯問題,如下為具體依賴關系圖:
在項目中創建實體 User
??配置 spring 容器的配置文件,在 resources 目錄下點擊 new -> XML Configuration File ->Spring Config 創建 spring-context.xml,并在其中配置一個 bean(被 spring 管理的對象)。
??其中 bean 的 id 表示該對象在容器中的唯一標識。class 表明該對象所屬的類型。property 相當于對象的屬性設置,spring 通過調研對象的 set 方法完成屬性設置。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="cn.hxzy.User"><property name="id" value="1"/><property name="name" value="張三"/></bean> </beans>??在主函數或測試類中獲取 spring 的容器,并從容器中獲取 bean 對象。
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml"); // 從 IOC 容器中獲取 bean 的實例 User bean = ctx.getBean(User.class); System.out.println(bean);??總結:如上操作即使用 spring 的語法在 spring 容器中創建一個被管理的對象。再通過 ApplicationContext(spring 上下文容器)獲取該對象,ApplicationContext 是一個接口,常用的實現類有 ClassPathXmlApplicationContext:從類路徑下加載 xml 配置文件獲取 spring 上下文容器和 AnnotationConfigApplicationContext:從配置類中加載 spring 容器信息。通過容器獲取 bean 常用三種方式如下:
Object getBean(String beanId) throws BeansException; <T> T getBean(String beanId, Class<T> var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException;??第一種是根據 bean 的 id 獲取,由于容器無法確定返回類型,故返回結果為 Object 類型。第二種傳入 bean 的類型故返回該類型的 bean。第三種根據類型獲取 bean,當該類型的 bean 存在多個是 spring 啟動會報錯。
三、構造注入
??在實際開發中有時需要被管理的對象沒有提供無參構造方法,因此我們需要在創建對象時直接傳入對應的值。spring 使用 constructor-arg 設置對象的構造方法的參數,通常可以使用 name 指定構造方法的參數名或通過 index 指定構造方法參數的索引。比如: 與下面設置 id 的方式等效。
<bean id="user2" class="cn.hxzy.User"><constructor-arg name="name" value="李四"/><constructor-arg name="id" value="2"/> </bean>注意:在 xml 中包含特殊字符,必須使用<![CDATA[*****]]> 包裹,且不能在寫在 constructor-arg 節點的屬性上。
<constructor-arg name="name" ><value><![CDATA[<李四]]></value> </constructor-arg>練習:
1.創建項目 spring-fruit01,分別使用普通屬性注入和構造注入的方式完成如下水果的創建。fruit(id,name,color)
fruit1(1,apple,red)屬性注入
fruit2(2,banner,yellow)構造注入
fruit3(3,pear,white)構造加屬性注入
fruit4(4,orange,)特殊字符注入
參考代碼:
<bean id="fruit1" class="cn.hxzy.Fruit"><property name="id" value="1"/><property name="name" value="apple"/><property name="color" value="red"/> </bean> <bean id="fruit2" class="cn.hxzy.Fruit"><constructor-arg index="0" value="2"></constructor-arg><constructor-arg index="1" value="banner"></constructor-arg><constructor-arg index="2" value="yellow"></constructor-arg> </bean> <bean id="fruit3" class="cn.hxzy.Fruit"><constructor-arg name="id" value="3"></constructor-arg><constructor-arg name="name" value="pear"></constructor-arg><constructor-arg name="color" value="white"></constructor-arg> </bean> <bean id="fruit4" class="cn.hxzy.Fruit"><constructor-arg name="id" value="4"></constructor-arg><constructor-arg name="name" value="orange"></constructor-arg><constructor-arg name="color"><value><![CDATA[<orange>]]></value></constructor-arg> </bean>四、級聯注入
??在 Spring 中可以通過一組內置的 xml 標簽(例如:<list>,<set> 或 <map>)來配置集合屬性。配置 java.util.List 類型的屬性,需要指定 <list>標簽,在標簽里包含一些元素。這些標簽可以通過 <value> 指定簡單的常量值,通過<ref> 指定對其他 Bean 的引用。通過<bean> 指定內置 Bean 定義。通過 <null/> 指定空元素。甚至可以內嵌其他集合。數組的定義和 List 一樣,都使用 <list> 配置 java.util.Set 需要使用 <set> 標簽,定義元素的方法與 List 一樣。
??在用戶實體中加入 Car 集合
public class User {......private List<Car> cars; }汽車實體
public class Car {private String company;private Integer maxSpeed;private Float price; }??級聯時使用 list 表明該處級聯類型為 list 集合,里面使用 ref 應用其他 bean 對象,級聯 set 與 map 也與此類似。
<bean id="user1" class="cn.hxzy.User"><property name="id" value="1"/><property name="name" value="張三"/><property name="cars"><list><ref bean="car1"/></list></property> </bean> <bean id="car1" class="cn.hxzy.Car"><property name="company" value="大眾"/><property name="maxSpeed" value="280"/><property name="price" value="30"/> </bean>注意:設置為空使用下面的語法
<property name="company"><null/></property>練習:
1.創建項目 spring-fruit02,在基本屬性設置的情況下增加特征(feature)和別名(otherName)兩個級聯屬性。
Fruit{id=1, name=‘pear’, color=‘white’, feature={表皮=粗糙, 肉質=甜美}, otherName=[雪梨, 大鴨梨]}
public class Fruit {private Integer id;private String name;private String color;private Map<String, String> feature;private Set<String> otherName; }參考代碼:
<bean id="fruit" class="cn.hxzy.Fruit"><property name="id" value="1"/><property name="name" value="pear"></property><property name="color" value="white"></property><property name="feature"><map><entry key="表皮" value="粗糙"/><entry key="肉質" value="甜美"/></map></property><property name="otherName"><set><value>雪梨</value><value>大鴨梨</value></set></property> </bean>五、單例與多例
??為了節省內存,spring 中的對象默認使用單例模式。即無論從容器中獲取多少次對象,得到的都是同一個。但在實際開發中有時會用到多例,即希望每次從容器中獲取對象都是新的對象。spring 提供 scop 屬性來指定對象獲取是單例還是多例。多例的 bean 又叫原型的。
??prototype:原型的。每次調用 getBean 方法都會返回一個新的 bean。且在第一次調用 getBean 方法時才創建實例。
??singleton:單例的。每次調用 getBean 方法都會返回同一個 bean。且在 IOC 容器初始化時即創建 bean 的實例。默認值
<bean id="user" class="cn.hxzy.User" scope="prototype"><property name="id" value="1"/><property name="name" value="張三"></property> </bean>應用場景:
??1.數據庫連接 Connection 對象不能設計成單例,否則會出現多個線程使用同一個連接完成數據庫的不同操作,也許上一個線程還沒有查詢完數據就會被下一個線程拿去修改數據庫記錄,非常容易出現錯誤。
??2.service 層的對象就不需要設計成原型的,因為 service 層沒有過多的參數,不容易導致線程安全問題,創建過多的對象反而耗用大量內存意義不大。
六、工廠方法創建 Bean
??在項目開發中,有時需要使用工廠方法創建 bean,spring 支持常用的工廠方法如靜態工廠方法創建和實例工廠方法創建 bean。
1.靜態工廠方法創建 bean
public class CarFactory {static Map<String, Car> cars = new HashMap<>();static {cars.put("car1", new Car("寶馬", 120, 122222.0));cars.put("car2", new Car("奧迪", 120, 122222.0));}public static Car getCar(String name) {return cars.get(name);} }獲取 bean
<bean id="car1" class="cn.hxzy.CarFactory" factory-method="getCar"><constructor-arg value="car2"/> </bean>2.實例工廠方法獲取 bean
public class CarFactory {Map<String, Car> cars = new HashMap<>();public CarFactory() {cars.put("car1", new Car("寶馬", 120, 122222.0));cars.put("car2", new Car("奧迪", 120, 122222.0));}public Car getCar(String name) {return cars.get(name);} }獲取bean
<bean id="carFactory" class="cn.hxzy.CarFactory"></bean> <bean id="car1" factory-bean="carFactory" factory-method="getCar"><constructor-arg value="car1"></constructor-arg> </bean>七、包掃描管理 bean
??使用 xml 方式配置 bean 的依賴關系復雜且麻煩,為了解決對象在容器注入麻煩的問題,spring 推出了包掃描與聲明類注解配合使用的方式,對于開發人員編寫的類只需要在包掃描范圍內,使用指定的聲明類注解即可將對象加入 spring 容器中。
??sping 使用 context:component-scan 將指定包下面的帶有聲明 bean 的注解的類加入到 spring 容器管理。
<context:component-scan base-package="cn.hxzy"/>??常用的聲明類注解有如下幾個,它們的功能和作用在 spring 中完全一模一樣,都是將自己交給 spring 管理。唯一的區別就是它們所用的業務環節不同。
- @Service 用于標注業務層組件
- @Controller 用于標注控制層組件
- @Repository 用于標注數據訪問組件,即 DAO 組件
- @Component 泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。
注入類注解:在 spring 容器管理的 bean 對象需要依賴其他 bean 對象時,就可以在對應對象屬性或其 set 方法上使用注入類注解完成依賴注入。spring 容器中常用 @Autowired 和 @Resource 兩個注解完成依賴注入。@Autowired 屬于 Spring 的注解,@Resource 不屬于 Spring 的注解,是 JDK1.6 支持的注解。它們的區別是:
@Autowired 默認按類型裝配, 依賴對象必須存在,如果要允許 null 值,可以設置它的 required 屬性為 false @Autowired(required = false) 也可以使用名稱裝配,配合 @Qualifier 注解
public class TestServiceImpl {@Autowired@Qualifier("userDao")private UserDao userDao; }@Resource 默認按名稱進行裝配,通過 name 屬性進行指定,name 為屬性的名字時可以省略。
案例:
dao 層模擬從數據庫查出數據,首先需要使用聲明類注解將自己注冊到容器。
@Repository public class PetDao {public List<Pet> getAll() {List<Pet> pets = new ArrayList<>();pets.add(new Pet("花花"));return pets;} }??service 層除了將自己注冊到容器,還依賴 dao 層的對象,使用注入類注解將容器內的對象注入到對應位置。
@Service public class PetService {@Autowiredprivate PetDao dao;public List<Pet> getAll() {return dao.getAll();} }view 層與服務層原理相同。
@Controller public class PetView {@Resourceprivate PetService petService;public void getAll() {List<Pet> list = petService.getAll();System.out.println(list);} }main 從容器中獲取 view 層對象即可調用它的方法,得到 dao 層返回的結果。
public class MainTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");PetView bean = context.getBean(PetView.class);bean.getAll();} }總結:將除了實體以外的其他對象加入 spring 容器管理,并通過彼此的依賴自動注入。使程序開發更加簡便靈活,在內存耗用,對象管理方面更加優秀。
八、SPEL與資源調用
??內容如下:
??如果該屬性需要的 spring 包掃描的類中使用可以使用 @Value("${name}") 獲取配置文件內的屬性。
@Service public class PropertyTest {@Value("${name}")private String id;public String getId() {return id;} }??在 spring 中加載配置文件也可以使用注解的方式 @PropertySource(“classpath:db.properties”) 它與 context:property-placeholder 是等效的。
??spring 不僅僅可以獲取配置文件里面的內容它還可以做一些簡單的運算,如下案例:可以注入其他對象的屬性、普通字符串、操作系統的信息、隨機數、某個文件的內容等。如下代碼在輸出 Resource 時用到 commons-io 工具類。
??依賴如下:
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version> </dependency>??案例:
import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service;@Service @PropertySource("classpath:db.properties") public class PropertyTest {@Value("${id}")private int id;//注入配置文件的屬性@Value("I love you")private String normal;//字符串原樣注入@Value("#{systemProperties['os.name']}")private String osName;//注入操作系統信息@Value("#{pet.name}")private String otherName;//注入容器內其它 bean 的屬性@Value("#{T (java.lang.Math).random()*100}")private Integer random;//注入 100 以下的隨機數@Value("classpath:1.txt")private Resource resource;//注入classpath下文本文件里面內容@Value("http://58.42.239.163:8888/")private Resource resourceUrl;//注入網站地址的響應內容public String toString1() throws Exception {return "[normal=" + normal + ",id="+id+", osName=" + osName + ", otherName=" + otherName+ ", random=" + random + ", resource=" + IOUtils.toString(resource.getInputStream())+ ", resourceUrl=" + IOUtils.toString(resourceUrl.getInputStream(), "UTF-8") + "]";} }注意:
1.在 spring 通過注解 @Value 中獲取 properties 文件里面的值使用 $ 前綴。
2.獲取系統信息、容器類其他對象的信息、方法調用后的結果等使用 # 前綴。
3.獲取文件或網頁內容不使用前綴,且使用 Resource 接收。
九、對象屬性拷貝(自)
??BeanUtils 在 spring 工具庫中是比較常用的對象屬性拷貝工具,BeanUtils.copyProperties(源頭,目標);一般使用如下:
User user1 = .....; User user2 = .....; BeanUtils.copyProperties(user1,user2);??當在完成兩個對象拷貝是需要負略某些屬性可以使用對應的重載方法 BeanUtils.copyProperties(源頭,目標,“忽略的屬性”); 但在實際開發中拷貝非空屬性是比較常用的。創建方法將對象的非空屬性列出后傳入 BeanUtils 即可拷貝非空屬性。
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import java.beans.PropertyDescriptor; import java.util.HashSet; import java.util.Set;public class BeanUtil {private static String[] getNullPropertyNames(Object source) {final BeanWrapper src = new BeanWrapperImpl(source);PropertyDescriptor[] pds = src.getPropertyDescriptors();Set<String> emptyNames = new HashSet<>();for (java.beans.PropertyDescriptor pd : pds) {Object srcValue = src.getPropertyValue(pd.getName());if (srcValue == null)emptyNames.add(pd.getName());}String[] result = new String[emptyNames.size()];return emptyNames.toArray(result);}public static void copyPropertiesIgnoreNull(Object source, Object target) {BeanUtils.copyProperties(source, target, getNullPropertyNames(source));}}十、單元測試
??在實際開發中有時需要對 spring 容器中的大量的類和方法進行測試,使用 main 方法顯然不能很好的滿足需求,單元測試更好的解決測試方面的注入和運行問題。使用 spring 的單元測試需要導入相應的依賴:spring-test,同時要求 junit 不小于 4.12 版本。
<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.12.RELEASE</version><scope>test</scope> </dependency> <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope> </dependency>引入依賴后在測試源碼目錄下創建如下類并添加相應的注解
import cn.hxzy.spring.view.PetView; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value = "classpath:spring-context.xml") public class AppTest {@Autowiredprivate PetView petView;@Testpublic void sendSimpleEmail() throws InterruptedException {petView.show();} }十一、spring與 mybatis 整合
??spring 能夠與常見框架整合,如 mybatis,hibernate,redis 等。這使得大部分框架中的對象都可以從 spring 中獲取到。而且對象被 spring 管理后可以很方便的使用 spring 的依賴注入和面向切面。
??使用 spring 與 mybatis 整合需要如下幾步:
??1.添加依賴:由于數據庫連接相關對象都交給 spring 管理,所以依賴中多出了 spring-jdbc 依賴。同時 mybatis 為了和 spring 整合開發了 mybatis-spring 整合包。
<!--spring --> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.12.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.12.RELEASE</version> </dependency><!--mybatis--> <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.2</version> </dependency> <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version> </dependency> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version> </dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency>2.配置數據庫連接信息,文件名通常為 db.properties
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///mydb jdbc.username=root jdbc.password=1234563.spring 核心配置文件,由于數據庫連接等對象都被 spring 管理,所以配置時不再需要 mybatis 的核心配置文件,如果在開發中確實需要用到 mybatis 的核心配置文件也可以配置 sqlsessionfactory 的 configlocation。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><context:component-scan base-package="cn.hxzy"/><context:property-placeholder location="classpath:db.properties"/><!-- 配置數據庫數據源--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!-- 創建 session 工廠--><bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="mapperLocations" value="classpath:mapper/*.xml"/></bean><!--告訴spring mybatis接口的位置--><bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="cn.hxzy.mapper"/></bean><!-- 配置事務管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 使用注解的方式完成事務控制--><tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/></beans>注意:
1.mapperScanner 配置主要配置 mybatis 的接口位置。
2.注解式事務是通過 @Transactional 注解即可完成該方法所有數據庫操作要么一起成功,要么一起失敗的業務邏輯。使用事務時數據庫引擎必須使用 innoDB。
@Transactional public void update(){User user1 = new User();user1.setId(2);user1.setName("O");userMapper.update(user1);System.out.println(1 / 0);User user2 = new User();user2.setId(3);user2.setName("Y");userMapper.update(user2); }3.spring5 版本不再支持原來的 mybatis 章節的 log4j 版本,為了顯示日志。通常我們使用 logback。導入如下依賴。
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version> </dependency>配置文件 logback.xml 放在 classpath 下。
<?xml version="1.0" encoding="UTF-8"?> <configuration><!--控制臺--><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p --- [%t] %-40.40logger{39} : %m%n</pattern></encoder></appender><!--根logger--><root level="DEBUG" additivity="false"><appender-ref ref="console"/></root> </configuration>章節練習:
1.IOC 綜合練習:Boss,Car,Meeting 三個實體存在依賴關系如下:
Car:屬性有 brand(品牌)、color(顏色)、parameter (參數 map)
Boss:屬性有 name(名字)、company(公司全稱)、car(擁有的車)
Meeting:屬性 theme(主題)、bosses (會議主題在 meet.properties 文件中)
綜合采用所學內容,設計并完成以上綜合練習。一次會議包含 張三,李四和王二三個 Boss,他們每個人都有自己的愛車 car,使用 spring ioc 的 xml 方式配置這些對象。并在單元測試中輸出結果如下:
Meeting{theme='全國程序員保護協會一次會議', bosses=[ Boss{name='張三', company='ABC', car=Car{brand='軒逸', color='紅色', parameter={參考價=9.98-14.30萬, 排量=1.6L}}}, Boss{name='李四', company='DEF', car=Car{brand='卡羅拉', color='白色', parameter={參考價=10.98-15.98萬, 排量=1.2L,1.5L,1.8L}}}, Boss{name='王二', company='GHI', car=Car{brand='哈弗H6', color='白色', parameter={參考價=9.98-15.48萬, 排量=1.5L,2.0L}}}]}參考代碼:
<context:property-placeholder location="classpath:meet.properties"/> <bean id="car1" class="cn.hxzy.Car"><property name="color" value="紅色"/><property name="brand" value="軒逸"/><property name="parameter"><map><entry key="參考價" value="9.98-14.30萬"/><entry key="排量" value="1.6L"/></map></property> </bean> <bean id="car2" class="cn.hxzy.Car"><property name="color" value="白色"/><property name="brand" value="卡羅拉"/><property name="parameter"><map><entry key="參考價" value="10.98-15.98萬"/><entry key="排量" value="1.2L,1.5L,1.8L"/></map></property> </bean> <bean id="car3" class="cn.hxzy.Car"><property name="color" value="白色"/><property name="brand" value="哈弗H6"/><property name="parameter"><map><entry key="參考價" value="9.98-15.48萬"/><entry key="排量" value="1.5L,2.0L"/></map></property> </bean> <bean id="boss1" class="cn.hxzy.Boss"><property name="name" value="張三"/><property name="company" value="ABC"/><property name="car" ref="car1"/> </bean> <bean id="boss2" class="cn.hxzy.Boss"><property name="name" value="李四"/><property name="company" value="DEF"/><property name="car" ref="car2"/> </bean> <bean id="boss3" class="cn.hxzy.Boss"><property name="name" value="王二"/><property name="company" value="GHI"/><property name="car" ref="car3"/> </bean> <bean class="cn.hxzy.Meeting"><property name="bosses"><list><ref bean="boss1"></ref><ref bean="boss2"></ref><ref bean="boss3"></ref></list></property><property name="theme" value="${theme}"/> </bean>總結
以上是生活随笔為你收集整理的spring(一)依赖注入与 SPEL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache日志分割及分析
- 下一篇: 第二期项目订房网错误分析