3.spring:自動裝配/Bean之間的關系/作用域/外部文件/spel/
1.自動裝配/手動裝配
xml配置文件裏的bean自動裝配
Spring IOC 容器裏可以自動的裝配Bean,需要做的僅僅是在<bean>的autowire屬性裏面指定自動裝配模式
->byType(根據類型自動進行裝配):若IOC容器裏需要有多個與目標Bean類型一樣的Bean,在這種情況子下,Spring無法判定那個Bean合適,所以不能執行自動裝配
->byName(根據名稱自動裝配):必須將目標Bean的名稱和屬性名設置完全相同,
->constuuctor(通過是構造器自動裝配):當bean中存在多個構造器時,這個方法將會復雜,不建議使用
一般情況下很少進行使用這個屬性
Car.java
public class Car { private String brand; private int price;
//...
}
Person .java
public class Person { private String name; private Address address; private Car car;
//...
}
Address .java
public class Address { private String city; private String street;
//...
}
applicationContext.xml
<!-- 自動裝配 --> <bean id="address" class="com.MrChengs3.autowire.Address" p:city="BeiJing" p:street="sanqing_Street"></bean> <bean id="car" class="com.MrChengs3.autowire.Car" p:brand="BMW" p:price="10000"></bean> <!-- 根據名字進行裝配和setter方式類似 byName根據bean的setter風格進行裝配,將address改為address1則不能自動進行,沒有匹配的則不裝配 byType:假設我們配了兩個address的變量,此時不唯一,不知道裝配那個--> <bean id="person" class="com.MrChengs3.autowire.Person" p:name="MrChengs" autowire="byType"></bean> <!-- 手動裝配 --> <bean id="person" class="com.MrChengs3.autowire.Person" p:name="MrChengs" p:car-ref="car" p:address-ref="address"></bean>
測試:
Person p = (Person) ctx.getBean("person"); System.out.println(p);
Person [name=MrChengs, address=Address [city=BeiJing, street=sanqing_Street],
car=Car [brand=BMW, price=10000]]
2.Bean之間的關系
繼承:
Spring允許繼承bean之間的配置,被繼承的bean稱為父類bean,繼承這個父bean的bean稱為字bean
子bean從父類中繼承配置,包括父類的屬性配置
子bean也可以覆蓋從父類繼承過來的配置
父類可以作為模板,也可以作為bean實例,若相把父類的作為模板,可以設置父類bean的abstract屬性為true,這樣spring將不會實例化這個Bean
並不是bean元素裏的屬性都會被繼承,比如autowire,abstract等
也可以忽略父bean的class屬性,讓子類指定子的類,面向共享的配置,但是此時abstract必須設為true
1、父bean是一個實例時。它本身是一個完整的bean
2、父bean是模板,抽象bean,不能被實例化,只是來被繼承。
父bean一定不能實例化,因為它沒有class屬性,實例化會跑異常。那就一定要寫abstract屬性,讓spring不實例化它。
當遇到一個類要實例化出很多相似的bean對象時,看起來是不是很不簡潔。
applicationContext.xml
<bean id="address" p:city="ShangHai" p:street="LaoRenJie" abstract="true"></bean> <!-- 配置的繼承,使用bean --> <bean id="address1" class="com.MrChengs3.autowire.Address" parent="address"></bean>
Address address1 = (Address) ctx.getBean("address1");
依賴:
Spring允許用戶通過depend-on屬性設置bean前置依賴關系,前置以來的bean會在本bean實例化之前創建好
如果依賴多個bean,則可以使用逗號,空格或的方式配置bean的名稱
我們需要讓某個屬性必須存在,就像必填項一樣。 用depends-on 依賴
這樣,依賴存在了,就可以正常實例化了
<bean id="car" class="com.MrChengs3.autowire.Car" p:brand="BMW" p:price="1234" ></bean> <!-- 配置Person,並且必須有一個關聯的car,就是說person這個bean依賴於car --> <bean id="person" class="com.MrChengs3.autowire.Person" p:name="MrChengs" p:address-ref="address1" depends-on="car"></bean>
3.bean的作用域
作用域:
singleton:單例,整個應用中只創建一個實例(默認)
prototype:原型,每次註入時都新建一個實例
session:會話,每個會話創建一個實例,在一個session會話中,是同一個bean,不同session就是不同bean
request:請求,每個請求創建一個實例,每一個HTTP請求生成一個新的bean
applicationContext.xml
<!-- bean的作用域 --> <!-- scope:bean的作用域 singleton(默認值):在容器初始化的時候創建bean的實例,整個容器的生命周期裏面僅僅只創建一個bean,單列的 prototype:原型的,容器創建初始化時,不創建bean的實例,而每次請求時都會創建一個新的bean實例,並返回 --> <bean id="car" class="com.MrChengs3.autowire.Car" p:brand="Ford"
p:price="4321" scope="singleton"></bean>
測試:
Car car = (Car) ctx.getBean("car"); Car car2 = (Car) ctx.getBean("car"); System.out.println(car ==car2);
true
scope="prototype"則為false
4.使用外部文件
propertie.properties
user=root password=1234 driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc\:mysql\://localhost\:3307/shijian
applicationContext.xml
<!-- 使用外部的屬性文件 --> <!-- 需要導入context命名空間 --> <context:property-placeholder location="classpath:propertie.properties"/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 使用外部話屬性文件 --> <property name="username" value="${user}"></property> <property name="password" value="${password}"></property> <property name="driverClassName" value="${driverClass}"></property> <property name="url" value="${jdbcUrl}"></property> </bean>
DataSource dataSource = (DataSource) ctx.getBean("dataSource",DataSource.class); System.out.println("執行中"); System.out.println(dataSource.getConnection()); System.out.println("結束");
${},代表引用外部的變量
通過把配置信息獨立到一個文件裏面,bean用${}方式引用, 便於維護、更清晰
如果響應修改只需要修改配置文件即可!
5.SpEl
SpEL---Spring Expression Language:
是一個支持運行時查詢和操作對象圖表達式語言、使用#{...}作為定界符,為bean屬性動態賦值提供了便利。
1) 為屬性賦值字面值
<bean id="address" class="com.MrChengs7.spel.Address"> <!-- 為屬性賦值字面值 --> <property name="city" value="#{‘beijing‘}"></property> <property name="street" value="Shangye"></property> </bean>
Address address= (Address) ctx.getBean("address"); System.out.println(address);
Address [city=beijing, street=Shangye]
2)引用 類的靜態屬性,用T()調用一個類的靜態方法,它將返回一個Class Object,然後再調用相應的方法或屬性
<bean id="car" class="com.MrChengs7.spel.Car"> <property name="brand" value="Aodi"></property> <property name="price" value="12345"></property> <!-- 引用 類的靜態屬性 --> <property name="circle" value="#{T(java.lang.Math).PI * 80}"></property> </bean>
Car car = (Car) ctx.getBean("car"); System.out.println(car);
Car [brand=Aodi, price=12345.0, circle=251.32741228718345]
3)其他
<bean id="person" class="com.MrChengs7.spel.Person"> <!-- 引用其他的bean --> <property name="car" value="#{car}"></property> <!-- 其他bean的屬性 --> <property name="city" value="#{address.city}"></property> <!-- 運算符的使用 --> <property name="info" value="#{car.price > 1000 ? ‘有錢‘ : ‘沒錢‘}"></property> <property name="name" value="MrChengs"></property> </bean>
Person p = (Person) ctx.getBean("person"); System.out.println(p);
Person [name=MrChengs, car=Car [brand=Aodi, price=12345.0, circle=251.32741228718345], city=beijing, info=有錢]
等待還有很多其他的....
3.spring:自動裝配/Bean之間的關系/作用域/外部文件/spel/