spring-01
1. 安裝spring插件
SPRING TOOL SUITE 是一個 Eclipse 插件,利用該插件可以更方便的在 Eclipse 平臺上開發基于 Spring 的應用。
- Install New Software...
- Add...
- Location
- 選擇Navigate to springsource-tool-suite-3.4.0.RELEASE-e4.3.1-updatesite.zip
- 取消勾選 Contact all updata......
- 點擊“Acailable Software Sites” 藍色字體 取消所有http的選項勾選
- 一直下一步
- 關于錯誤處理
jdk版本 spring 版本 eclipse版本 引起的
2. spring概述
2.1spring是個啥?
開源的輕量級的框架,一個IOC(DI)和AOP容器框架,關于框架的特性,spring俗稱開發框架的粘合劑
- 輕量級:Spring是非侵入性的,基于Spring開發的應用中的對象可以不依賴Spring的API
- 依賴注入:(DI---dependency Injection、IOC ---Inversion of Control)
- 面向切面編程:(AOP aspect oriented programming)
- 容器:Spring 是個容器,因為它包含并且管理應用對象的生命周期
- 框架:Spring實現了使用簡單的組件配置組合成一個復雜的應用,在Spring中可以使用xml和java注解組合這些對象
- 一站式:在IOC和AOP的基礎上可以整合各個企業應用的開源框架和第三方類庫
spring提供了JavaEE各層的解決方案
web表現層(頁面數據顯示、頁面跳轉調度):SpringMVC Struts2
service業務層(業務處理和功能邏輯、事務控制):IoC、AOP、事務控制
dao持久層(數據存取和封裝):jdbcTemplate,HibernateTemplate,ORM框架
2.2spring框架runtime
- test:spring提供的測試功能
提供對使用JUnit和TestNG來測試Spring組件的支持,它提供一致的ApplicationContexts并緩存這些上下文,它還能提供一些mock對象,使得你可以獨立的測試代碼
- AOP:實現aop功能需要的依賴
- AOP:提供了符合AOP 聯盟規范的面向方面的編程實現,讓你可以定義如方法攔截器和切入點,從邏輯上講,可以減弱代碼的功能耦合,清晰的被分離開。而且,利用源碼級的元數據功能,還可以將各種行為信息合并到你的代碼中
- Aspect:提供了對AspectJ的集成
- Instrumentation
- WEB:需要spring完成web相關功能時需要
- Web:提供了基礎的web功能,例如文件上傳,集成IoC容器,遠程過程訪問及對web Service支撐
- Servlet:提供了Web應用的MVC實現,Spring MVC框架提供了基于注解的請求資源注入、更簡單的數據綁定、數據驗證等及一套非常易用的JSP標簽,完全無縫與Spring其他技術協作
- Portlet模塊,提供了在Portlet環境下的MVC實現
- Data Access/Integration(數據訪問/集成部分):spring封裝數據訪問層相關內容
- JDBC:Spring對JDBC封裝后的代碼
- ORM:提供了常用的“對象/關系”映射APIs的集成層,封裝了持久層框架的代碼:如Hibernate MyBatis
- transactions:對應spring-tx.jar,聲明式事務使用,只要是Spring管理的對象都能得到spring管理事務的好處
- OXM:提供一個支持Object和XMl進行映射的抽象層
- JMS模塊:提供一套"消息生產者、消費者"模板用于更加簡單的使用JMS,JMS用于用于在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。
- Core Container:核心容器,Spring啟動的基本條件
- Beans:Spring負責創建對象并管理對象
- Core:核心類 ,和Beans模塊提供了Spring最基礎的功能,提供了IoC和依賴注入的特性,這里的基礎概念是BeanFactory,它提供對Factory模式的經典實現來消除對程序性單例模式的需要,并真正地允許你從程序邏輯中分離出依賴關系和配置。
- Context:上下文參數,獲取外部資源或管理注解
Context模塊基于Core和Beans來構建,Context封裝包繼承了beans包的功能,還增加了其他的功能,核心接口是ApplicationContext
- SqEl:expression.jar 表達式語言模塊,提供了在運行期間查詢和操作對象圖的強大能力。 "
2.3 spring的優點
1. 方便解耦,簡化開發
Spring就是一個大工廠,可以將所有對象創建和依賴關系維護,交給Spring管理
2. AOP編程的支持
Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能
3. 聲明式事務的支持
只需要通過配置就可以完成對事務的管理,而無需手動編程
4. 方便程序測試
對Junit4支持,可以通過注解方便的測試Spring程序
5. 方便集成各種優秀的框架
不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz、webservice、activity等)的直接支持
6. 降低JavaEE API的使用難度
Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低
3. IoC&DI
IOC控制返轉
IoC完成的事情 由程序員主動通過new實例化對象事情轉交給Spring完成
IoC是一種思想,是控制反轉的思想,解耦的思想
spring是該思想的一種實現,因此spring容器也通常稱之為IoC容器
將對象創建權利交給Spring工廠進行管理
控制:控制類的對象
反轉:轉交給spring對象
底層實現:工廠模式+反射+配置文件
最大作用:解耦 ,解除了對象管理和程序員之間的耦合,程序員不需要管理對象
DI 依賴注入
在spring框架負責創建Bean對象時,動態的將依賴對象注入到Bean組件(將另外一個Bean對象動態的注入到另外一個bean中)
IoC和DI是同一件事情,都是將對象控制權交給第三方(spring)管理,只是站在不同角度而已(IoC是目的,DI是手段)
簡單的說,就是我們類里需要另一個類,只需要讓Spring幫我們創建 ,這叫做控制反轉,然后Spring幫我們將需要的對象設置到我們的類中,這叫做依賴注入。
4. 代碼實現
4.1導包
四個核心包一個日志包
commous-logging-1.1.3.jar
spring-beans-4.2.4RELEASE.jar
spring-context-4.2.4RELEASE.jar
spring-core-4.2.4RELEASE.jar
spring-expression-4.2.4RELEASE.jar
4.2配置文件
beans.xml
<?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">
<!-- id 表示獲取到對象標識class 創建哪個類的對象-->
<bean id="people" class="com.yn.People"/>
</beans>
4.3People類
public class Person {
private String name;
private int age;
public Person() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4.4測試
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
//使用Java反射來實現 默認是單例模式來創建對象
Person p=(Person)ac.getBean("person");
Person p2 = ac.getBean("person",Person.class);
System.out.println(p);
System.out.println(p2);
}
5. 依賴注入的三種方式
- 屬性注入
- 通過構造方法設置值.
- 設置注入(通過 set 方法)
- 如果屬性是基本數據類型或 String 等簡單
<bean id="people" class="com.yn.People">
<property name="name" value="tom" ></property>
<property name="age" value="18"></property>
</bean>
- 如果屬性是 Set<?>
<property name="sets">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</set>
</property>
- 如果屬性是 List<?>
<property name="list">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
- 如果屬性是數組
<property name="strs" >
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
- 如果屬性是 map
<property name="map">
<map>
<entry key="a" value="b" >
</entry>
<entry key="c" value="d" >
</entry>
</map>
</property>
- 如果屬性 Properties 類型
<property name="demo">
<props>
<prop key="key">value</prop>
<prop key="key1">value1</prop>
</props>
</property>
- 配置工具類集合
<!-- 首先導入util命名空間 -->
xmlns:util="http://www.springframework.org/schema/util"
<util:list id="pets">
<ref bean="cat"/>
<ref bean="dog"/>
</util:list>
- 使用p命名空間
<!-- 首先導入p命名空間 -->
xmlns:p="http://www.springframework.org/schema/p"
<bean id="pet" class="cn.yn.Pet" p:petName="鸚鵡" p:petType="鳥"></bean>
<bean id="test1" class="cn.yn.Person" p:name="張全蛋" p:age="10"
p:pet-ref="pet"></bean>
<!-- 使用p命名空間(spring 2.5版本引入的) 可以簡化bean的配置 -->
- null值
<constructor-arg name="name">
<null/>
</constructor-arg>
- 自動裝配
autowire = "byName" || "byType" 不推薦使用。
<!--
可以通過autowire屬性設置bean的自動裝配 。
byName 根據bean的名字和bean,setter風格的屬性名進行自動裝配,如有匹配則自動裝配,沒有不裝配。
byType 根據bean的類型,和當前bean屬性的類型進行自動裝配。如果ioc容器有1個以上類型匹配的bean的時候,則會拋出異常。
constructor 當前bean中有多個構造器的時候 會很復雜不推薦使用該方式。
自動裝配的弊端。
1.autowire屬性是配置在bean級別的,如果只希望裝配個別屬性,則不夠靈活。
2.要么根據類型 要么根據名字自動裝配 不能兩個一起使用。
在使用spring整合第三方框架的時候 會使用autowire 。。。
-->
<bean id="xm" class="cn.yn.Person" p:name="小明" autowire="byType">
</bean>
<bean id="pet1" class="cn.yn.Pet" p:petName="發福蝶"></bean>
<bean id="pet2" class="cn.yn.Pet" p:petName="小腦斧"></bean>
- 構造器注入
- 無參構造創建:默認情況.
- 有參構造創建:需要明確配置
- 需要在類中提供有參構造方法
- 在 配置文件 中設置調用哪個構造方法創建對象
- index : 參數的索引,從 0 開始
- name: 參數名
- type:類型(區分開關鍵字和封裝類 int 和 Integer)
- ref:引用其他對象
<!--當屬性值中包含特殊字符時,使用<![CDATA[ 特殊字符 ]]>
-->
<constructor-arg type="java.lang.String" ><value><![CDATA[<xiaoma>]]></value></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
- 工廠方法注入 很少使用,不推薦
6. Bean 的作用域
由spring創建的bean對象在什么情況下有效。
類別 說明
singleton 在spring IoC容器中僅存在一個Bean實例,bean以單例方式存在
prototype 每次從容器中調用Bean時,都會返回一個實例,即每次調用getBean()時,相當于new一個對象
request 每次HTTP請求都會創建一個新的Bean,該作用域僅適用于WebApplicationContext環境
session 同一個HTTP session共享一個Bean,不同的Session使用不同的Bean,僅適用于WebApplicationContext環境
globalSession 一般用于Porlet應用環境,僅適用于WebApplicationContext環境
Porlet: 基于Java的web組件
項目開發中通常使用singleton和prototype
7.Bean的生命周期
通過spring工廠,可以控制bean的生命周期
- 通過構造器或工廠方法創建Bean實例
- 為Bean的屬性設置值,和對其他Bean的引用
- 調用Bean的初始化方法
- Bean可以使用了
- 當容器關閉,調用Bean的銷毀方法
在 Bean 的聲明里設置 init-method 和 destroy-method 屬性, 為 Bean 指定初始化和銷毀方法.
spring提供可一個Bean后置處理器,允許在調用初始化方法前后對Bean進行額外的處理
Bean后置處理器對IoC容器里所有的Bean實例逐一處理,作用:檢測bean屬性的正確性,或者根據特定的標準更改bean屬性
8. 使用外部屬性文件
在配置文件中配置bean時,有時候需要混入系統部署的數據信息。
例如:文件路徑,數據源配置。
實際上需要將這些數據跟bean的配置分離。
spring提供了一個PropertyPlaceholderConfigurer的BeanFactory后置處理器。
可以使用${var}的形式,從屬性配置文件中讀取屬性,并使用這些屬性。
spring,2.5之后。可以通過<context:property-placeholder location="classpath:db.properties"
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"></property>
<property name="password" value="root123"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
</bean>
9. spring的工廠
Spring提供了兩種類型的IoC容器實現
- BeanFactory:IOC容器的基本實現
采用延時加載,第一次getBean時才會初始化Bean對象
- ApplicationContext:提供了更多的高級特性,是BeanFactory的子接口
BeanFactory是Spring框架的基礎設施,面向Spring本身;ApplicationContext面向Spring框架的開發者
幾乎所有的應用場合都直接使用 ApplicationContext 而非底層的 BeanFactory .無論使用何種方式, 配置文件時相同的.
ApplicationContext
ApplicationContext 應用上下文 ,用來加載spring框架的配置文件,來構建spring的工廠對象,也稱為Spring容器的上下文對象,也稱為spring的容器
主要實現類
- ClassPathXmlApplicationContext:從 類路徑下加載配置文件
- FileSystemXmlApplicationContext: 從文件系統中加載配置文件
ApplicationContext在初始化上下文時就是實例化所有的單例的Bean
10.Bean 之間的關系
- 繼承
抽象Bean:abstract=“true”,不能被IoC實例化,只能用來被繼承配置
如果一個Bean的Class值沒有被指定,那么這個Bean的abstract屬性必須為true
使用Bean的parent屬性來制定繼承哪一個Bean
<bean id="person" p:country="china" p:age="12" abstract="true"></bean>
<bean id="xm" class="cn.yn.Person" p:name="小明" pareant="person"></bean>
- 依賴
通過depends-on 設置前置依賴的bean,依賴的bean會在當前bean實例化之前創建好。
如果依賴多個bean 可以使用 , | 和 空格 來區分多個bean。
11. 配置Bean 的三種方法
- 反射
- 工廠實現
- 注解
11.1工廠實現Bean的配置
11.1.1靜態工廠實現
public class StaticFactory {
private static Map<String, Person> persons=new HashMap<String,Person>();
static {
persons.put("tom", new Person("Tom"));
persons.put("jack", new Person("Jack"));
}
//靜態工廠方法
public static Person InstanceFactory(String name){
return persons.get(name);
}
}
//配置文件
<!-- 靜態工廠方法配置Bean -->
<bean id="tom" class="com.yn.spring01.StaticFactory" factory-method="InstanceFactory">
<constructor-arg value="tom"></constructor-arg>
</bean>
//測試
ApplicationContext ac=new ClassPathXmlApplicationContext("com/yn/spring01/beans.xml");
Person bean = (Person) ac.getBean("tom");
System.out.println(bean);
11.2 實例工廠實現
public class InstanceFactory {
Map<String ,Person> map=null;
public InstanceFactory(){
map=new HashMap<String ,Person>();
map.put("xixi", new Person("Xixixixi"));
map.put("haha", new Person("Hahahahah"));
}
public Person getPerson(String name){
return map.get(name);
}
}
//配置文件
<!-- 實例工廠配置Bean -->
<bean id="instance" class="com.yn.spring01.InstanceFactory"></bean>
<bean id="xixi" factory-bean="instance" factory-method="getPerson">
<constructor-arg value="xixi"></constructor-arg>
</bean>
//測試
Person bean2 = (Person) ac.getBean("xixi");
System.out.println(bean2);
11.1.3 FactoryBean
public class PersonFactoryBean implements FactoryBean<Person> {
private String name;
public void setName(String name) {
this.name = name;
}
public Person getObject() throws Exception {
// TODO Auto-generated method stub
return new Person(name);
}
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Person.class;
}
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
//配置文件
<!-- FactoryBean 配置bean實例-->
<bean id="p" class="com.yn.spring01.PersonFactoryBean">
<property name="name" value="FactoryBean"></property>
</bean>
//測試
Person bean3 = (Person) ac.getBean("p");
System.out.println(bean3);
11.2 注解方式配置Bean
在使用注解時在之前的五個包里,還要加一個AOP包
在使用注解時,要在配置文件中開啟掃描包
<!--
base-package 屬性指定一個需要掃名的基類包,Spring容器會掃描這個基類包里及其子包中所有的的類
當需要掃描多個包時,可以使用逗號隔開
如果需要掃描特定的類,而非基類包下的所有類,可使用resource-Pattern 屬性過濾特定的類
-->
<context:component-scan base-package="com" />
對于掃描的組件,spring有默認的命名策略:使用類名 第一個字母小寫 也可以使用value屬性標識組件
組件包裹 4 個
@Conponent 基本注解,標識一個受Springf IoC 容器管理的組件
@Respository 標識持久層
@Service 標識業務層
@Controller 標識控制層
組件裝配
注入包裹 3 個
@AuthWired 自動裝配具有兼容類型的單個Bean屬性
@Resource 注解要求提供一個 Bean 名稱的屬性,若該屬性為空,則自動采用標注處的變量或方法名作為 Bean 的名稱
@Inject 和 @Autowired 注解一樣也是按類型匹配注入的 Bean, 但沒有 reqired 屬性建議使用 @Autowired 注解
@AuthWired: 可以使用在屬性,set方法和構造器的前面
@Qualifier:提供了Bean的名稱,Spring允許對方法的入參標注@Qualifier指定注入Bean的名稱
12. spEl表達式
spring表達式語言 即 spEL:是一個運行時查詢和操作對象圖的強大表達式語言
使用#{}作為定界符 為bean屬性動態賦值提供了便利
<property name="test" value="#{5}"/>
<property name="test" value="#{3.14}"/>
<property name="test" value="#{1e4}"/>
<property name="test" value="#{'哈哈'}"/>
<property name='test' value='#{"嘿嘿"}'/>
<!--引用其他bean對象,等價于ref屬性。-->
<property name="pet" value="#{pet1}"></property>
<!--引用其他bean對象的屬性。 -->
<property name="pet" value="#{pet1.petName}"></property>
<!--拿到方法的返回值。 -->
<property name="name" value="pet1.toString()"></property>
<!--鏈式調用。-->
<property name="name" value="pet1.toString().toUpperCase()"></property>