一.Spring概念
1.是一個開源的輕量級架構
2.spring核心主要兩部分
(1)aop:面向切面編程,擴充功能不是修改代碼實現
(2)ioc:控制反轉:把對象的建立不通過new的方式,而是交給spring配置建立對象
3.spring是一站式架構
在javaee的三層結構中,每一層都提供不同的解決辦法
web層:springMVC
service:spring的ioc
dao層:spring的jdbcTemplate
4.ioc
1)把對象的建立交給spring管理
2)ioc操作兩部分
A.ioc的設定檔方式
B.ioc的註解方式
3)底層原理(搞內聚低耦合)
A.底層使用技術
a.xml設定檔
b.dom4j解決XML
c.工廠設計模式
d.反射
4)設定檔步驟
A:spring核心設定檔名稱和位置不是固定的,建議放到src下面,官方建議名稱為applicationContext.xml
B:引入schema約束
<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"> <!--此處配置實體類--></beans>
C:設定物件
<!--無參構造配置--><bean id="user" class="cn.zsl.bean.User"></bean>
5.Bean管理——設定檔方式
(1)Bean執行個體化方式三種
A:使用類的無參構造建立(重點)
B:使用靜態工廠建立:建立靜態方法返回對象
C:使用執行個體工廠建立:不是靜態方法,而是建立類的對象來返回
(2)Bean標籤常用屬性
id:起名稱,id屬性值名稱任意命名,不能包含特殊符號。根據id得到設定物件
class:建立對象所在類的全路徑
name:功能和id屬性一樣,id屬性不能包含特殊符號,但是再那麼屬性值裡面可以包含特殊符號,基本不用了。
scope:包含以下值
singleton:預設值,單例,只有一個對象
prototype:多例
request:建立對象把對象放到request裡面
session:建立對象把對象放到session裡面
globalSession:建立對象把對象放到globalSession裡面
(3)屬性注入:建立對象的時候向類裡面的屬性設定值
A:Java中的屬性注入方式 三種
a.使用有參構造方法注入
b.使用set方法注入
c.使用介面注入
B:設定檔注入類中屬性值,只支援上面a、b兩種方法
a.使用有參構造方法注入,使用constructor-arg標籤 ,name屬性工作表示成員變數名,value表示要傳入的值
<bean id="user" class="cn.zsl.bean.User"> <constructor-arg name="name" value="張三"></constructor-arg></bean>
b.使用set方法注入,使用property標籤,name屬性工作表示成員變數名,value表示要傳入的值
<bean id="user" class="cn.zsl.bean.User"> <property name="name" value="張三"></property></bean>
C:注入物件類型屬性(重點)
若A類中含有B類的對象,用ioc來實現的方法
a.在A中把B作為類型屬性
b.產生B類型的set方法
c.在設定檔中注入對象屬性,在A中添加屬性標籤property,name屬性工作表示成員變數名,ref表示類B類配置bean標籤中的id值
<bean id="b" class="cn.zsl.bean.B"></bean><bean id="a" class="cn.zsl.bean.A"> <property name="name" ref="b"></property></bean>
D:注入複雜資料
a.數群組類型:使用property標籤下的list標籤下的value標籤對數組賦值
b.List集合:使用property標籤下的list標籤下的value標籤對List集合賦值
c.map集合:使用property標籤下的map標籤下的entry標籤對map集合賦值,key是鍵value是值
d.properties:使用property標籤下的props標籤下的prop標籤對properties賦值,key是實體中的鍵
<bean id="user" class="cn.zsl.bean.User"> <!-- 對數組屬性賦值 --> <property name="array"> <list> <value>張三</value> <value>李四</value> <value>王五</value> </list> </property> <!-- 對List屬性賦值 --> <property name="list"> <list> <value>手機</value> <value>電腦</value> <value>平板</value> </list> </property> <!-- 對map屬性賦值 --> <property name="map"> <map> <entry key="aa" value="tom"></entry> <entry key="bb" value="jerry"></entry> <entry key="cc" value="friends"></entry> </map> </property> <property name="properties"> <props> <prop key="username">root</prop> <prop key="password">123</prop> </props> </property> </bean>
E:IOC和DI區別
IOC:控制反轉,把對象的建立交給spring管理
DI:依賴注入,向類中的屬性進行注入值
關係:依賴注入不能單獨存在,需要在IOC基礎上完成操作。
6.Spring整合Web項目原理
(1)載入spring核心設定檔
new對象,功能可以實現,效率很低
(2)實現思想:要把載入設定檔和建立對象過程在伺服器啟動時完成
(3)實現原理:
A:ServletContext對象
B:監聽器
(4)具體流程
A.在伺服器啟動時,系統為每個項目建立一個ServletContext對象
B.在ServletContext對象建立的時候使用監聽器可以監聽到ServletContext對象在什麼時候建立
C.監聽到ServletContext建立時,項目載入spring設定檔,把設定檔中的設定物件進行建立
D.把建立出來的對象放在ServletContext域對象裡面(setAttribute()方法)
E.擷取對象時,到ServletContext域得到對象(getAttribute()方法)
7.Bean管理——註解方式
(1)註解:代碼裡面的特殊標記,使用註解可以完成功能
註解寫法:@註解名稱(屬性名稱=屬性值)
註解可以使用在類、方法和屬性上面
(2)步驟:
A.匯入jar包,包括基本spring包還有一個註解包
B.建立類,屬性和方法
C.建立設定檔,引入約束,開啟註解掃描
<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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 開啟註解掃描 到包中掃描類、方法、屬性上是否有註解 如果向掃描多個類中的註解,可以讓base-package="cn.zsl" ,如果是不同包下的類,甚至可以讓base-package="cn" --> <context:component-scan base-package="cn.zsl.bean"></context:component-scan> <!-- 只會掃描屬性上面的註解 --> <context:annotation-config></context:annotation-config></beans>
D.註解建立對象 4個註解
@Component(vlaue=”user”) //和< bean id=”user” class=”“>效果一樣,user表示對象名
@Controller:web層
@Service :業務層
@Repository :持久層
4個效果是一樣的,用法也一樣。
E:建立單一實例對象
@scope(value=”singleton”) //singleton預設值,單一實例 、prototype多執行個體 其他用法見設定檔方式
(3)屬性注入
A.@Autowired自動注入
B.@Resourse(name=”user”) :name表示賦值,如果注入物件類型,則和註解建立對象的value值要相同或者設定檔方式建立對象的id相同
註:使用註解方式,A類中不需要設定B類對象屬性的set方法,標籤自動注入
(4)注入物件類型屬性
若A類中含有B類的對象,用註解方式來實現
A:建立A類和B類
B:註解方式建立A、B類的對象
C:在A類中定義B類型屬性,用註解標籤注入該對象屬性
7.設定檔和註解混合方式
建立對象都是使用設定檔方式,注入屬性都是用註解方式
二.AOP
1.AOP:面向切面編程,採取橫向抽取機制,取代了傳統的縱向繼承體系重複性代碼。
2.AOP原理:
3.AOP操作術語:
4.aspectj: 在spring裡面進行aop操作,使用aspectj實現
(1)aspectj不是spring一部分,和spring一起使用進行aop操作
(2)Spring2.0以後新增了對AspectJ支援
(3)使用aspectj實現aop有兩種方式
A.基於aspectj的xml配置
B.基於aspectj的註解方式
5.aspectj的使用準備
(1)設定檔引入約束
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --></beans>
(2)使用運算式配置切入點
A.切入點:實際增強方法
B.常用的運算式 execution(<存取修飾詞>?<傳回型別><方法名>(<參數>)<異常>)
a. execution(* cn.itcast.aop.Book.add(..)) :表示cn.itcast.aop包下Book類的add()方法
b. execution(* cn.itcast.aop.Book.*(..)):表示cn.itcast.aop包下Book類的所有方法
c. execution(* * .*(..)) :表示所有方法
d. 匹配所有save開頭的方法 execution(* save*(..)):表示所有以save開頭的方法
6.設定檔方式使用aspectj的aop操作
(1)添加增強類和方法
如果是要添加around環繞增強方法,需要對該方法添加一個ProceedingJoinPoint類型的形參,通過該形參的proceed()方法來調用被增強方法,該proceedingJoinPoint.proceed()就表示被增強方法
public void aroundAdd(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //方法之前 System.out.println("環繞之前"); //調用被增強方法 proceedingJoinPoint.proceed() ; //方法之後 System.out.println("環繞之後"); }
(2)設定物件,在設定檔中對要使用的類進行添加設定物件
<!-- 對Book類的add()方法添加一個MyBook類中的增強方法 --> <!-- 1 設定物件 --> <bean id="book" class="cn.zsl.bean.Book"></bean> <bean id="myBook" class="cn.zsl.bean.MyBook"></bean> <!-- 2 配置aop操作 --> <aop:config> <!-- 2.1配置切入點 --> <aop:pointcut expression="execution(* cn.zsl.bean.Book.*(..))" id="pointcut1"/> <!-- 2.2配置切面:把增強用到方法上面 --> <aop:aspect ref="myBook"> <!-- 配置增強型別 aop:before:前置增強 aop:after:後置增強 aop:around:環繞增強 ... method:增強類裡面使用哪個方法作為增強方法 pointcut-ref:要增強切入點(方法),要和上面定義的相同 --> <aop:before method="beforeAdd" pointcut-ref="pointcut1"/> <aop:after method="afterAdd" pointcut-ref="pointcut1"/> <aop:around method="aroundAdd" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config>
7.log4j : 使用log4j查看日誌
使用方法:
(1)匯入log4j的jar包
(2)複製log4j的設定檔,複製到src下面
設定記錄層級
(1)info:看到基本資料
(2)debug:看到更詳細資料
8.Spring整合Web項目
每次訪問action時候,都會載入spring設定檔
(1) 解決方案:
A.在伺服器啟動時候,建立對象載入設定檔
B.底層使用監聽器、ServletContext對象
(2)在spring裡面不需要我們自己寫代碼實現,會幫我們封裝
A.封裝了一個監聽器,只需要 配置監聽器 就可以了
B.配置監聽器之前做事情:匯入spring整合web項目jar包(spring-web-4.2.4.RELEASE.jar)
C.指定載入spring設定檔位置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:bean1.xml</param-value></context-param>
9.註解方式使用aspectj的aop操作
(1)建立增強類和方法
(2)配置類和增強類對象
(3)設定檔開啟aop操作
<!-- 開啟aop操作 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
(4)在增強類上面使用註解完成aop操作
A.在類上添加@Aspect標籤
B.在方法上添加@Before、@After、@Around等標籤,子標籤value值為 常用的運算式 execution(<存取修飾詞>?<傳回型別><方法名>(<參數>)<異常>),如下:
@Before(value=”execution(* cn.zsl.bean.Book.*(..))”)
10.Spring的jdbcTemplate操作
(1)spring架構一站式架構
針對javaee三層,每一層都有解決技術
在dao層,使用 jdbcTemplate
(2)spring對不同的持久化層技術都進行封裝
dbcTemplate使用和dbutils使用很相似,都資料庫進行crud操作
(3)使用方法
A.匯入jar包
B.建立對象,設定資料庫資訊
C.建立jdbcTemplate對象,設定資料來源
D.調用jdbcTemplate對象裡面的方法實現操作
增刪改都是調用update()方法實現
//設定資料庫資訊 DriverManagerDataSource dataSource = new DriverManagerDataSource() ; dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///springjdbcTemplatetest"); dataSource.setUsername("root"); dataSource.setPassword("root"); //建立jdbcTemplate對象,設定資料來源 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource) ; //調用jdbcTemplate對象裡面的update方法實現操作 String sql = "insert into user value(?,?)" ; int rows = jdbcTemplate.update(sql,"zhangsan","26") ; System.out.println(rows);
(4)查詢資料操作
設定資料庫和建立jdbcTemplate對象步驟一樣,調用方法不同
A.尋找返回一個值
// 尋找返回一個值,queryForObject()方法,第一個參數表示sql語句,第二個參數表示傳回值的類型的class檔案 String sql = "select count(*) from user"; int count = jdbcTemplate.queryForObject(sql, Integer.class); System.out.println(count);
B.尋找返回一個對象,這時需要自己建立一個RowMapper介面的對象,用於封裝尋找到的資料
// 尋找返回對象,調用queryForObject(),第一個參數表示sql語句,第二個參數表示RowMapper介面對象,表示擷取到一行資料的User對象,第三個參數是可變參數 String sql = "select * from user where username = ?"; User user = jdbcTemplate.queryForObject(sql, new MyRowMapper() , "zhangsan"); System.out.println(user);
class myRowMapper implements RowMapper<User>{ @Override public User mapRow(ResultSet rs, int num) throws SQLException { //1從結果集裡把資料得到 String username = rs.getString("username") ; String password = rs.getString("password") ; //2把得到的資料封裝到對象裡面 User user = new User() ; user.setUsername(username); user.setPassword(password); return user ; }}
C.查詢返回list集合
// 尋找返回對象,調用query()方法,第一個參數表示sql語句,第二個參數表示RowMapper介面對象 String sql = "select * from user"; List<User> list= jdbcTemplate.query(sql, new MyRowMapper()) ; System.out.println(list);
11.配置c3p0串連池和dao使用jdbcTemplate
(1)配置c3p0串連池
(2)dao使用jdbcTemplate
1)建立service和dao,配置service和dao對象,在service注入dao對象
2)建立jdbcTemplate對象,把模板對象注入到dao裡面
3)在jdbcTemplate對象裡面注入dataSource
12.交易管理
(1)事物:對資料庫操作的最基本單元
(2)事物特性:原子性、一致性、隔離性、持久性
(3)不考慮隔離會產生的問題:
髒讀:一個事務讀到另一個事務未提交的更新資料。
不可重複讀取:一個事務兩次讀同一行資料,可是這兩次讀到的資料不一樣。
幻讀:一個事務執行兩次查詢,但第二次查詢比第一次查詢多出了一些資料行。
丟失更新:撤消一個事務時,把其它事務已提交的更新的資料覆蓋了。
(4)解決方案:設定隔離等級
(5)Spring交易管理api