Spring學習筆記(五)
1、SpringAOP
1.1、AOP的概念
Aspect oritention programming(面向切面編程),Spring的AOP使用動態代理實現,如果一個類實現了接口,那麽spring就使用JDK的動態代理完成AOP,如果一個類沒有實現接口,那麽spring就是用cglib完成AOP;
AOP當中的概念:
①切入點Pointcut:在哪些類,哪些方法上面切(where);
②通知/增強Advice:在方法的什麽時機(when)做什麽(what);
③切面Aspect:切入點+通知:什麽時間,什麽地點,幹什麽
④織入Weaving:把切面加入到對象,並創建出代理對象的過程(Spring自動搞定)
1.2、xml中配置aop
1、添加jar包
com.springsource.org.aopalliance-1.0.0.jar、com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2、引入aop的命名空間
<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" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <context:property-placeholder location="classpath:db.properties"/> <context:component-scan base-package="cn.org.kingdom"/> </beans>
3、xml配置
<aop:config> <!--做什麽 --> <aop:aspect ref="txManager"> <!--什麽地點,哪些方法上--> <aop:pointcut expression="execution(* cn.org.kingdom.aop_xml.*ServiceImpl.*(..)) " id="txPoint"/> <!--時機:方法前、方法後、方法前後 --> <aop:before method="beginTransaction" pointcut-ref="txPoint"/> </aop:aspect> </aop:config>
註意執行表達式的格式:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
modifiers-pattern:修飾符
ret-type-pattern:返回值的類型
declaring-type-pattern:這個方法的類名
name-pattern:方法名
param-pattern:參數
throws-pattern:異常
語法案例:
1.任意公共方法的執行:
execution(public * *(..))
2.任何一個名字以“set”開始的方法的執行:
execution(* set*(..))
3.AccountService接口定義的任意方法的執行:
execution(* com.xyz.service.AccountService.*(..))
4.在service包中定義的任意方法的執行:
execution(* com.xyz.service.*.*(..))
5.在service包或其子包中定義的任意方法的執行:
execution(* com.xyz.service..*.*(..))
1.3、Spring中的各種通知
aop:before(前置通知):在方法執行之前執行增強操作(增強類中的指定增強方法)
<aop:before method="beginTransaction" pointcut-ref="txPoint"/>
aop:after-returning(後置通知):在方法正常執行完成之後執行增強操作;
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
異常通知:在業務方法中出現異常,需要調用的增強操作 throwing="ex":決定方法定義為:public void rollback(Throwable ex):
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
aop:after(最終通知):在方法執行之後執行,相當於在finally裏面執行
<aop:after method="close" pointcut-ref="txPoint"/>
aop:around(環繞通知):把方法的執行包裹起來,環繞通知有兩個要求
? 1、方法必須要返回一個Object(返回的結果)
? 2、方法的第一個參數必須是ProceedingJoinPoint(可以繼續向下傳遞的切入點)
<aop:around method="around" pointcut-ref="txPoint"/>
完整代碼
//PersonService
package cn.org.kingdom.service;
public interface PersonService {
public abstract int add(String msg);
}
//PersonServiceImpl
package cn.org.kingdom.service.impl;
import org.springframework.stereotype.Service;
import cn.org.kingdom.service.PersonService;
@Service("personService")
public class PersonServiceImpl implements PersonService {
public int add(String msg) {
System.out.println("執行add操作");
System.out.println(10/0);
return 0 ;
}
}
//事務管理類
package cn.org.kingdom.ts;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
@Component("ts")
public class Transaction {
public void begin(){
System.out.println("開啟事務");
}
public void commit(){
System.out.println("提交事務");
}
public void rollback(Throwable ex){
System.out.println("回滾事務");
System.out.println("發生的異常通知是:"+ex);
}
public void closeConnection(){
System.out.println("關閉連接");
}
public Object around(ProceedingJoinPoint pjp){
Object value = null ;
try{
begin();
value = pjp.proceed();
commit();
}catch(Throwable e) {
rollback(e);
}finally{
closeConnection();
}
return value;
}
}
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"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:property-placeholder location="classpath:db.properties"/>
<!-- 掃包 -->
<context:component-scan base-package="cn.org.kingdom"/>
<aop:config>
<aop:aspect ref="ts">
<aop:pointcut expression="execution(* cn.org.kingdom.service..*.*(..))" id="mypointcut"/>
<aop:around method="around" pointcut-ref="mypointcut"/>
</aop:aspect>
</aop:config>
</beans>
1.4、aop的註解配置
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"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:property-placeholder location="classpath:db.properties"/>
<!-- 掃包 -->
<context:component-scan base-package="cn.org.kingdom"/>
<aop:aspectj-autoproxy/>
</beans>
java配置
package cn.org.kingdom.ts;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component("ts")
@Aspect
public class Transaction {
@Pointcut(value="execution(* cn.org.kingdom.service..*.*(..))")
public void pointcut(){}
//註意value為方法名,並且加括號
@Around(value="pointcut()")
public Object around(ProceedingJoinPoint pjp){
Object value = null ;
try{
begin();
value = pjp.proceed();
commit();
}catch(Throwable e) {
rollback(e);
}finally{
closeConnection();
}
return value;
}
public void begin(){
System.out.println("開啟事務");
}
public void commit(){
System.out.println("提交事務");
}
public void rollback(Throwable ex){
System.out.println("回滾事務");
System.out.println("發生的異常通知是:"+ex);
}
public void closeConnection(){
System.out.println("關閉連接");
}
}
Spring學習筆記(五)