目錄
0.前言
1.簡介
AOP的目的:
AOP的優勢:
2.XML方式實作AOP
3.Spring的各種增強:
4/注釋的方式實作AOP
5.Spring的AOP配置,到底使用XML,還是注解:
0.前言
在上一篇文章,我們已經實作了動态的為目标對象做功能增強? 為什麼還要學Spring 的AOP呢?

原因是:在為N個service提供代理的時候,我們需要在xml中配置N次.
1.簡介
Spring的AOP: 什麼叫做AOP:Aspect oritention programming(面向切面程式設計)
AOP能夠将那些與業務無關,卻為業務子產品所共同調用的邏輯或責任(例如事務處理、日志管理、權限控制等)封裝起來, 便于減少系統的重複代碼,降低子產品間的耦合度,并有利于未來的可拓展性和可維護性。
降低子產品的耦合度、使系統容易擴充、更好的代碼複用性.
Spring的AOP使用動态代理實作:
如果一個類實作了接口,那麼spring就使用JDK的動态代理完成AOP;
如果一個類沒有實作接口,那麼spring就是用cglib完成AOP;
AOP當中的概念:
1、切入點(Pointcut):在哪些類,哪些方法上切入(where);
2、增強(Advice): 早期翻譯為通知,在方法執行的什麼時機(when:方法前/方法後/方法前後)做什麼(what:增強的功能);
3、切面(Aspect): 切面=切入點+通知,通俗點就是:在什麼時機,什麼地點,做什麼增強!
4、織入(Weaving): 把切面加入到對象,并建立出代理對象的過程。(該過程由Spring來完成)。
2.XML方式實作AOP
1).Spring AOP開發依賴的jar:
spring-aop-4.1.2.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2).配置aop命名空間:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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 ">
</beans>
<!-- 配置AOP:1.切面:What 2.切如位置:Where 3.切入時機:When -->
<aop:config>
<!-- What:做什麼增強 -->
<aop:aspect ref="txManager">
<aop:pointcut expression="execution(* com.common.service.*Service.*(..))" id="txPoint"/>
<!-- When:在什麼時機做增強(業務方法前/後/前後) -->
<!-- <aop:before method="begin" pointcut-ref="txPoint"/>
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
<aop:after method="close" pointcut-ref="txPoint"/> -->
<aop:around method="allWork" pointcut-ref="txPoint"/>
</aop:aspect>
</aop:config>
Notes:
在所有的業務層方法上做增強: execution(* com.pss.service.*Service.*(..))
3.Spring的各種增強:
配置XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
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">
<!-- 配置AOP:1.切面:What 2.切如位置:Where 3.切入時機:When -->
<aop:config>
<!-- What:做什麼增強 -->
<aop:aspect ref="txManager">
<aop:pointcut expression="execution(* com.common.service.*Service.*(..))" id="txPoint"/>
<!-- When:在什麼時機做增強(業務方法前/後/前後) -->
<!-- <aop:before method="begin" pointcut-ref="txPoint"/>
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
<aop:after method="close" pointcut-ref="txPoint"/> -->
<aop:around method="allWork" pointcut-ref="txPoint"/>
</aop:aspect>
</aop:config>
<!-- 配置事務管理器 -->
<bean id="txManager" class="com.common.TransactionManager"/>
<!--配置Dao -->
<bean id="employeeDao" class="com.common.dao.impl.EmployeeDaoImpl"/>
<!-- 配置Service -->
<bean id="employeeService" class="com.common.service.impl.EmployServiceImpl">
<property name="dao" ref="employeeDao"/>
</bean>
</beans>
特别注意事務處理檔案:@Aspect
package com._07_springaop_anno;
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("txManager")
@Aspect
public class TransactionManager {
@Pointcut("execution(* com._07_springaop_anno.service.*Service.*(..))")
public void txPointcut(){
}
public void begin() {
System.out.println("事務開始");
}
public void commit() {
System.out.println("事務送出");
}
public void rollback() {
System.out.println("事務復原");
}
public void close() {
System.out.println("釋放資源");
}
@Around("txPointcut()")
public Object allWork(ProceedingJoinPoint Pjp) {
begin();
Object ret=null;
try {
ret=Pjp.proceed();
commit();
} catch (Throwable e) {
rollback();
}finally {
close();
}
return ret;
}
}