Spring4_Day01
Spring的IOC註解開發(重點)
入門案例
- 創建一個web項目
- 引入相應的包
3. 創建applicationContext.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"
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">
</beans>
- 編寫相關的類
package com.lld.Dao.Impl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.lld.Dao.UserDao;
@Component("UserDao")//這一句話相當於<bean id="UserDao" class="com.lld.Dao.Impl.UserDaoImpl" />
public class UserDaoImpl implements UserDao {
@Value("曲光光")//類似於將值注入到name中
private String name;
@Override
public void save() {
System.out.println("UserDao執行成功......"+name);
}
}
- 在applicationContext.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"
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">
<context:component-scan base-package="com.lld"/><!-- 該段說明com.lld包下面的都使用註解的方法執行 -->
</beans>
- 編寫測試類
@Test
/*
* 註解方式
*/
public void demo02(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("UserDao");
userDao.save();
}
- 運行結果
Spring的IOC註解詳解
@Component:組件(作用在類上)
- @Controller :WEB 層
- @Service : 業務層
- @Repository : 持久層
屬性注入的註解:(使用註解注入的方式,可以不提供set方法)
- @Value() :用於注入普通類型
- @Autowired():自動裝配
1.默認按照類型進行匹配
2.按照名稱注入
@Qualifier :強制使用名稱注入
- @Resource(name=" ")相當於
@Autowired和@Qualifier(" ")一起使用
生命週期注入
- @PostConstruct :創建時調用
- @PreDestroy :銷燬時調用
作用範圍註解
-
@scope("")
1. singleton :單例 2. prototype :多例 3. request :創建後存入request域中 4. session :創建後存入session域中 5. globalsession :應用在web項目中,必須在porlet環境下使用。但是如果沒有這種環境,相對於session。
IOC的XML和註解開發比較
XML和註解的比較
- 適用場景
xml:任何場景(結構清晰,方便維護)
註解:有些地方用不了,在這個類不是自己編寫的時候,註解無法往源代碼上加(開發方便)
XML和註解整合開發
- XML管理Bean,註解完成屬性注入
- 在使用註解和xml整合開發時將<context:component-scan base-package=“com.lld”/>換成<context:annotation-config />
<!-- <context:component-scan base-package="com.lld"/>該段說明com.lld包下面的都使用註解的方法執行 -->
<context:annotation-config /><!--在只使用註解進行屬性注入時,使用該標籤-->
AOP概述(面向切面編程)
什麼是AOP
爲什麼學習AOP
對程序進行增強:在不修改源碼的情況下
- AOP可以進行權限校驗,日誌記錄,性能監控,事務控制
SpringAOP的由來
AOP 最早由 AOP 聯盟的組織提出的,制定了一套規範.Spring 將 AOP 思想引入到框架中,必須遵守 AOP 聯盟的規範
底層實現
代理機制:
- Spring 的 AOP 的底層用到兩種代理機制:
- JDK 的動態代理 :針對實現了接口的類產生代理.
- Cglib 的動態代理 :針對沒有實現接口的類產生代理. 應用的是底層的字節碼增強的技術 生成當前類的子類對象.
Spring的基於Aspectj的開發
AOP開發中的相關術語及解釋
* joinpoint(連接點):所謂連接點是指那些被攔截到的點。在 spring 中,這些點指的是方法,因爲 spring 只支持方法類型的連接點.
* Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義.
* Advice(通知/增強):所謂通知是指攔截到 Joinpoint 之後所要做的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
* Introduction(引介):引介是一種特殊的通知在不修改類代碼的前提下, Introduction 可以在運行期爲類動態地添加一些方法或 Field.
* Target(目標對象):代理的目標對象
* Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程.spring 採用動態代理織入,而 AspectJ 採用編譯期織入和類裝在期織入
* Proxy(代理):一個類被 AOP 織入增強後,就產生一個結果代理類
* Aspect(切面): 是切入點和通知(引介)的結合
入門練習
1. 創建web項目引入jar包
2.編寫目標類(被增強的類)
- 接口
package demo2;
public interface ProductDao {
public void save();
public void update();
public void delete();
public void find();
}
- 實現類
package demo2;
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("商品保存...");
}
@Override
public void update() {
System.out.println("商品更新...");
}
@Override
public void delete() {
System.out.println("商品刪除...");
}
@Override
public void find() {
System.out.println("尋找商品...");
}
}
3.編寫增強類
package demo2;
public class MyAspectXml {
public void before(){
System.out.println("進行權限校驗...............");
}
}
4.添加配置文件(applicationContext.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"
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 -->
<!-- 把目標類交給spring管理 -->
<bean id="ProductDao" class="demo2.ProductDaoImpl" />
<!-- 將切面類交給spring管理 -->
<bean id="MyAspectXml" class="demo2.MyAspectXml" />
<!-- 進行AOP配置 -->
<aop:config>
<!-- 配置被增強的方法 -->
<aop:pointcut expression="execution(* demo2.ProductDao.save(..))" id="pointcut1"/>
<!--
1. 配置增強的方法
* ref:增強的類的id
-->
<aop:aspect ref="MyAspectXml">
<!--
* method:使用增強類的那一個方法增強
* pointcut-ref:被增強的方法
-->
<aop:before method="before" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>
5.整合Junite測試
- 導入jar包
spring-test-4.2.4.RELEASE.jar
- 添加註解
@RunWith(SpringJUnit4ClassRunner.class) #固定格式
@ContextConfiguration(“classpath:applicationContext.xml”) #classpath後面寫要讀取得配置文件
- 測試代碼
package demo2;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) //固定格式
@ContextConfiguration("classpath:applicationContext.xml") //classpath後填寫要讀取得配置文件
public class demo2 {
@Resource(name="ProductDao") //使用屬性注入
private ProductDao ProductDao;
@Test
public void demo01(){
ProductDao.save();
ProductDao.delete();
ProductDao.find();
ProductDao.update();
}
}
Spring通知解釋
1. 前置通知:在目標方法執行前進行操作
- 前置通知:獲得切入點信息
2. 後置通知:在目標方法執行後操作
- 後置通知:獲得方法值
3. 環繞通知:在目標方法執行前和執行後操作
- 環繞通知:
4. 異常拋出通知:在程序出現異常時進行操作
5. 最終通知:無論代碼是否有異常,總是會執行
6. 引介通知(不會用)
- 增強類代碼
package demo2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspectXml {
/**
* 前置通知
* @param joinPoint
*/
public void before(JoinPoint joinPoint){
System.out.println("進行權限校驗..............."+joinPoint);
}
/**
* 後置通知
* @param result
*/
public void writeLog(Object result){
System.out.println("進行日誌記錄................."+result);
}
/**
* 環繞通知
* @param joinPoint
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint joinPoint)throws Throwable{
System.out.println("環繞前通知......");
Object object = joinPoint.proceed();
System.out.println("環繞後通知......");
return object;
}
/**
* 異常通知
* @param ex
*/
public void afterThrowing(Throwable ex){
System.out.println("異常拋出通知"+ex.getMessage());
}
public void after(){
System.out.println("最終通知");
}
}
- 被增強類代碼
package demo2;
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("商品保存...");
}
@Override
public void update() {
System.out.println("商品更新...");
}
@Override
public String delete() {
System.out.println("商品刪除...");
return "曲禿";
}
@Override
public void find() {
System.out.println("尋找商品...");
}
}
- 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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 -->
<!-- 把目標類交給spring管理 -->
<bean id="ProductDao" class="demo2.ProductDaoImpl" />
<!-- 將切面類交給spring管理 -->
<bean id="MyAspectXml" class="demo2.MyAspectXml" />
<!-- 進行AOP配置 -->
<aop:config>
<!-- 配置被增強的方法 -->
<aop:pointcut expression="execution(* demo2.ProductDao.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* demo2.ProductDao.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* demo2.ProductDao.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* demo2.ProductDao.find(..))" id="pointcut4"/>
<!--
1. 配置增強的方法
* ref:增強的類的id
-->
<aop:aspect ref="MyAspectXml">
<!--
* aop:before:前置通知
* method:使用增強類的那一個方法增強
* pointcut-ref:被增強的方法
-->
<aop:before method="before" pointcut-ref="pointcut1"/>
<!-- aop:after-returning:後置通知 -->
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
<!-- aop:around:環繞通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
<!-- aop:after-throwing:異常拋出通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
<!-- aop:after -->
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
</beans>
切面表達式
execution(表達式)
表達式:
[方法訪問修飾符] 方法返回值 包名.類名.方法名(方法的參數)
public * cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.UserDao+.*(..)
* cn.itcast.spring.dao..*.*(..)