一、Spring定義
Spring是一個開源框架,為簡化企業級開發應用而生,使用Spring可以使簡單的JavaBean實現以前只有EJB才能實現的功能,它是一個IOC(DI)(依賴注入)和AOP(面向切面編程)容器框架。
- 一站式:在IOC和AOP基礎上可以整合各種企業應用的開源框架和第三方類庫。
二、環境搭建
- 1、新建工程
- 2、導入五個必備jar包
commons-logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
三、Spring具體應用
1、IOC&DI
Paste_Image.png
- IOC前生
1) 分離接口與實現
Paste_Image.png
2)工廠設計模式
Paste_Image.png
3)反轉控制
Paste_Image.png
2、IOC中Bean的配置
- 1、基于xml文件
創建HelloWorld類,包含一個name對象和一個hello()方法。
創建SpringBean配置文件,命名為applicationContext.xnl,并配置內容。
<!--
id:標識容器中的bean,id唯一
class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求bean中必須帶有無參的構造器
-->
<bean id="helloWorld" class="com.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
//創建Spring的IOC容器對象
//ApplicationContext 代表IOC容器
//ClassPathXmlApplicationContext:ApplicationContext 接口的實現類,該實現類從類路徑下加載配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("appllicationContext.xml");
//從IOC容器中獲取Bean實例
//利用id定位IOC容器中的bean,還可以同類型HelloWorld.class來獲得,此時IOC容器中bean必須只有一個
HelloWorld helloWorld=(HelloWorld)ctx.getBean("helloWorld");
//調用類中方法
helloWorld.hello();
Paste_Image.png
Paste_Image.png
2、配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法&實例工廠方法)、FactoryBean
3、IOC的依賴注入
1)屬性注入
<bean id="helloWorld" class="com.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
2)構造器注入
<bean id="car" class="com.bean.Car">
<constructor-arg value="Audi"></constructor-arg>
<constructor-arg value="ShangHai"></constructor-arg>
</bean>
當存在重載構造器時,可以再constructor-arg中添加位置(index)或者類型(type)來進行區分
外部bean的引入:
<bean id="person" class="com.bean.Person">
<property name="name" value="Tom"></property>
<property name="age" value="24"></property>
<property name="car" reg="car"></property>
</bean>
Paste_Image.png
Paste_Image.png
3)工廠方法注入(很少使用,不推薦)
注意:
- a、內部bean不能被外部引用,只能在內部使用。
- b、級聯屬性:bean支持為級聯屬性賦值,但必須初始化后才能進行賦值。和struts2不同
- c、集合屬性:
<bean id="person2" class="com.bean.Person">
<property name="name" value="Mike"></property>
<property name="age" value="23"></property>
<property name="cars" >
<list>
<ref bean="car"/>
<ref bean="car1"/>
<ref bean="car2"/>
</list>
</property>
</bean>
Paste_Image.png
Paste_Image.png
<!--配置properties屬性,如連接數據庫-->
<bean id="dataSource" class="class.bean.DataSource>
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">123456</prop>
<prop key="jdbcUrl">jdbc:mysql:///test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
配置獨立的集合bean,當多個bean都需要用到這個集合時,可以直接進行引用,需要導入util命名空間:
<uti-list>
<ref bean="car"/>
<ref bean="car2"/>
</uti-list>
- 通過p命名空間未bean賦值,需要先導入p命名空間
<bean id="person3" class="com.bean.person" p:name="Jack" p:age="34" p:car-ref="cars" ></bean>
- 4、自動裝配
Paste_Image.png
<bean id="car" class="com.bean.Car" p:brand="Aodi" p:price="30000"></bean>
<bean id="adress" class="com.bean.Ardress" p:city="BeiJing" p:street="HongQi"></bean>
<!--byName自動裝配是根據bean的名字和當前bean的setter方法的屬性名進行自動裝配,當bean的id變成car1是就無法裝配car;
byType根據bean的類型和當前bean屬性的類型進行自動裝配,若此時IOC容器中有兩個以上的類型匹配bean,則會拋出異常。
-->
<bean id="person" class="com.bean.Person" p:name="Tom" autowire="byName"></bean>
- 5、自動裝配的缺點
Paste_Image.png
- 6、bean的繼承
<bean id="adress" class="com.bean.Adress" p:city="BeiJing" p:street="Dazhogn"></bean>
<bean id="adress2" parent="adress" p:street="Dazhogn"></bean>
Paste_Image.png
當某一個bean沒有指定的class屬性時,他必須是一個抽象bean,否則會報錯。
- 7、bean的作用域
<!--
使用bean的scope屬性來配置bean的作用域
singleton:默認值。容器初始時創建bean實例,在整個容器的生命周期中只創建這一個bean,單例的。
prototype:原型的。容器初始化時不創建bean實例,在每次請求時都創建一個新的bean,并返回。
-->
<bean id="car" class="com.bean.Car">
<constructor-arg value="Audi"></constructor-arg>
<constructor-arg value="ShangHai"></constructor-arg>
</bean>
- 8、bean外部屬性文件
原因:在配置文件里 配置bean時,有時需要在bean的配置里混入系統部署的細節信息(例如:文件路徑,數據源配置信息等)。而這些部署細節實際上需要和bean的配置分離。
已導入數據源為例:
首先導入c3p0-0.9.1.2.jar包和mysql驅動包
新建一個文件db.properties,寫入要進行導入的屬性
user=root
password=123456
jdbcUrl=jdbc:mysql:///test
driverClass=com.mysql.jdbc.Driver
<!--導入屬性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="class.bean.DataSource>
<property name="properties">
<props>
<prop key="user" value=${user}></prop>
<prop key="password" value=${password}></prop>
<prop key="jdbcUrl" value=${jdbcUrl}></prop>
<prop key="driverClass" value=${driverClass}></prop>
</props>
</property>
</bean>
- 9、Spring表達式語言SpEL:
Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
<bean id="car" class="com.bean.Car">
<property name="brand" value="Audi"></property>
<property name="price" value="300000"></property>
<!--tyrePerimeter表示輪胎周長,使用SpEL引用類的靜態屬性-->
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI*80}></property>
</bean>
<bean id="preson" class="com.bean.Person">
<!--使用SpEl引用其他bean-->
<property name="car" value="#{car}"></property>
<!--使用SpEL引用其他bean的屬性-->
<property name="city" value="#{adress.city}"></property>
<!--使用SpEL的運算符-->
<property name="info" value="#{car.price>300000 ? '金領':'白領'}></property>
</bean>
- 10、bean的生命周期(視頻10)
Paste_Image.png
Paste_Image.png
public class Car(){
public Car(){
System.out.println("Car Constructor.....");
}
private String brand;
public void setBrand(){
System.out.println("serBrand...");
this.brand=brand;
}
public void init(){
System.out,println("init...");
}
public xoid destory(){
System.out.println("destory...");
}
}
<bean id="car" class="com.bean.Car"
init-method="init"
destory-method="destory">
<property name="brand" value="Audi"></property>
</bean>
<!--
實現BeanPostProcessor接口,并具體提供
Object postProcessBeforeInitialization(Object bean,String beanName):init-method之前調用
Object postProcessAfterInitialization(Object bean,String beanName):init-method之后調用
的實現
bean:bean實例本身
beanName:IOC容器中配置的bean的名字
返回值:實際返回給用戶的bean,可以通過以上兩個方法修改返回的bean,甚至返回一個新的bean
-->
<bean class="com.bean.MyBeanPostProcessor"></bean>