Spring簡介
分層的,full-stack的輕量級開源框架
Spring兩大核心
- IoC控制反轉 (反轉的是對象的創建權) 最大的優點是解耦合
- AOP面向切面編程 底層實現是動態代理 作用:程序方法在不修改的情況下進行增強
Spring的各個層的解決方案:
- web層: SpringMVC
- service層 :
- DAO層:
- spring JDBC Templae(類似DBUtils)
- Spring Data JPA\Redis\Solr\ES等
Spring的優勢
- 方便解耦 簡化開發
- AOP編程的支持
- 聲明式事務控制
聲明式:與之對應的是編程式 : XML和註解都稱爲聲明
- 方便程序的測試
- 方便集成各種優秀框架
- 降低JavaEE的API的使用難度(封裝)
Spring的發展
- Spring Boot (輕代碼 輕配置)
- Spring Security 安全框架
- Spring Cloud 用於分佈式開發
Spring快速入門(IoC:讓Spring框架創建Bean對象)
- 導入Spring相關jar包
- 導入核心容器的4個jar: beans, core, context, expression
- 框架會訪問日誌文件,導入日誌相關API: apache-commons-logging.jar
- 開發中習慣讓logging去繼承log4j ,自動集成 5.
- 創建bean
- 創建xml
- 測試
配置文件的配置
配置文件放在src目錄下,自己可以起名字,但是一般都是使用applicationContext.xml
0.導入約束
約束的位置在壓縮包
spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html
約束爲
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns=http://www.springframework.org/schema/beans ①
xsi:schemaLocation="http://www.springframework.org/schema/beans ② http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ③">
① Xmlns(XML NameSpace) 聲明命名空間,建議是用網址做命名空間,但並不會去訪問改網址, 僅僅是 namespace 和 xsd(xsd 是 spring 這個 xml 的 schema 文件,裏面定義配置內容)裏 聲明的 targetNamespace 保持一致 . 注:這裏命名空間是改不了的,其實是在代碼中也寫死了,可以打開 spring-beans3.2.0.M1-sources.jar 包的 org\springframework\beans\factory\xml\BeanDefinitionParserDelegate.java 查看對 http://www.springframework.org/schema/beans這個namespace的定義。
② schemaLoacation .用於綁定命名空間的 schema 文件,通常是用 URL 值對,中間用空格隔 開,前面 URL 是命名空間,後面 URL 爲 schema 的文件地址
③ xsd 的存放地址,如果沒有聲明,eclipse 會去網上下載.
1.基本配置
使用bean標籤進行配置,和以前三層架構解耦合用的BeanFactory差不多,只有”暱稱”和路徑
- id:bean的實例,在spring容器中一個唯一的標識
- class:bean的全限定名
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
2.Bean標籤中scope的配置
scope的選擇:
- singleton(默認值):單例
- prototype:原形 多例
需要注意的是,單例模式下,配置文件被加載,spring容器創建的時候,Bean對象就被創建了;而在多例模式下,在調用getBean的方法的時候,Bean對象才被創建
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" scope="prototype"></bean>
3.Bean生命週期相關的方法配置
也是Bean標籤中的屬性
- init-method:指定Bean初始化的時候,執行的方法
- destroy-mothod:指定Bean銷燬時執行的方法
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
通過這兩個屬性的設置,Bean中任何一個方法,都可以充當初始化方法,或銷燬方法
單例對象生命週期歸容器管理
多例歸JVM垃圾回收機制管理
4.Bean實例化的三種方式
1.通過Bean無參構造創建對象(以上例子都是通過該方式創建的,也是最常用的方法)
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
2.通過靜態工廠的方式創建對象
如果一個Bean可以通過一個工廠的某個方法獲得,name我們可以使用靜態工廠的方式獲取它
它有三個屬性 id–>和以前一樣,用來標識這個Bean; class–>這個class是工廠的位置,因爲這個模式是通過工廠獲取的Bean; method–>標識出具體哪一個方法用來生成我們想要的Bean
<bean id="userDao" class="com.cuixiaoming.factory.StaticBeanFactory" factory-method="getUserDao"></bean>
3.通過實例工廠的方式創建對象
這個和上一個的區別是,這種方法中,工廠Bean已經被配置到了spring容器中,所以我們不需要用class標識出工廠的位置,我們是用另一個屬性factory-bean
,標上工廠的id即可
<bean id="beanFactory" class="com.cuixiaoming.factory.InstanceBeanFactory"></bean>
<bean id="userDao" factory-bean="beanFactory" factory-method="getUserDao"></bean>
經過測試我發現,這兩個工廠的方式的時候,當spring容器加載的時候,factory-method
標註的方法都會執行一次,然後等到每次創建對象的時候,又會執行;
5.依賴注入(DI)的設置
注入之前,要在被注入的Bean中將注入的東西設爲私有變量,並且提供set方法
property標籤(位於Bean標籤內)
- name: 是該實體的set方法的屬性名稱
- ref: 代表引用的id 引用容器中的那一個bean
- value: 注入普通字符串
- list: 注入list集合
- map: 注入map集合
- props: 注入props集合
1.注入Bean
我們用最基本的形式,要想執行dao層方法,需要先獲得service對象,然後service對象再獲得dao層對象,從而執行dao層方法,也就是說,需要在spring容器中獲取兩次;
如果,我們通過注入,將dao層對象注入到service對象中,我們在獲得service對象的時候,就能一起獲取到dao層對象,如下圖所示;
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao" ></property>
</bean>
2.注入普通字符串
將一個字符串設爲私有變量,並提供名爲setStr()的set方法,這樣我們創建對象的時候,它裏面已經包含這個字符串變量了;
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="str" value="這是一個value"></property>
</bean>
3.注入集合
注入集合是非常重要的知識點
一般來說,也是先設置成私有變量並提供set方法;然後在property中寫個name,然後在標籤內部寫集合標籤
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<!-- list集合的注入 -->
<property name="strList" >
<list>
<value>第一個</value>
<value>第二個</value>
<value>第三個</value>
</list>
</property>
<!-- map集合的注入,裏面兩個user放在最下面了 -->
<property name="userMap">
<map>
<entry key="user1" value-ref="user1"></entry>
<entry key="user1" value-ref="user2"></entry>
</map>
</property>
<!-- property集合的注入-->
<property name="prop">
<props>
<prop key="p1">123</prop>
<prop key="p2">456</prop>
<prop key="p3">789</prop>
</props>
</property>
</bean>
<!-- map集合裏面的兩個user -->
<bean id="user1" class="com.cuixiaoming.domain.User">
<property name="username" value="張三"></property>
<property name="age" value="23"></property>
</bean><bean id="user2" class="com.cuixiaoming.domain.User">
<property name="username" value="李四"></property>
<property name="age" value="24"></property>
</bean>
6.屬性注入的三種方式
1.set注入
上面這些方式都是採用的set注入,就是在被注入的Bean裏面,將注入的東西提取私有,提供set方法,不再贅述
2.有參構造注入
通過被注入的Bean提供有參和無參構造,(這種注入不使用無參構造,但是沒有無參構造會導致其他功能不能使用,一般來說,只要給出有參構造,就要同時給出無參構造)
public UserDaoImpl() {
System.out.println("dao層無參構造執行了");
}
public UserDaoImpl(String username,User user) {
System.out.println("dao層有參構造執行了");
System.out.println("username="+username);
System.out.println("user=" +user);
}
配置文件
在Bean標籤裏面使用constructor-arg標籤,這個標籤可以使用鍵值,也可以繼續注入其他Bean
<bean id="user1" class="com.cuixiaoming.domain.User">
<property name="username" value="張三"></property>
<property name="age" value="23"></property>
</bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl">
<constructor-arg name="username" value="奧特曼"></constructor-arg>
<constructor-arg name="user" ref="user1"></constructor-arg>
</bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
需要注意的是,你的bean中constructor-arg的數據要至少和一個構造方法所有參數吻合,不然會報錯
3.p命名空間注入
這個方法也是使用set方法進行的注入,不過,語法非常簡單
首先,在約束上面加上這一句,就是把第一個約束複製改一下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<!--加上下面這一句,通過第一句修改而來-->
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
可以看出,它可以替代所有的set注入,而且語句極其簡單
<bean id="user1" class="com.cuixiaoming.domain.User" p:username="張三" p:age="23"></bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" p:str="這是一個字符串" p:user-ref="user1"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
7.導入其他的配置文件
這個是用於分佈式開發,把多個配置文件合成一個
使用下面這個標籤即可
<import resource=""/>