AOP面向切面編程

1.AOP

Aop(aspect object programming)面向切面編程
  功能: 讓關注點代碼與業務代碼分離!spring

關注點express

  重複代碼就叫作關注點;編程

切面spa

  關注點造成的類,就叫切面(類)!代理

  面向切面編程,就是指對不少功能都有的重複的代碼抽取,再在運行的時候往業務方法上動態植入「切面類代碼」。code

切入點xml

  執行目標對象方法,動態植入切面代碼。對象

  能夠經過切入點表達式,指定攔截哪些類的哪些方法; 給指定的類在運行的時候植入切面類代碼。blog

  Aop實現的原理就是代理。接口

2.Spring中的aop編程

1) 先引入aop相關jar文件 (aspectj aop優秀組件)

spring-aop-3.2.5.RELEASE.jar 【spring3.2源碼】

aopalliance.jar 【spring2.5源碼/lib/aopalliance】

aspectjweaver.jar 【spring2.5源碼/lib/aspectj】或【aspectj-1.8.2\lib】

aspectjrt.jar 【spring2.5源碼/lib/aspectj】或【aspectj-1.8.2\lib】

注意: 用到spring2.5版本的jar文件,若是用jdk1.7可能會有問題。

須要升級aspectj組件,即便用aspectj-1.8.2版本中提供jar文件提供。

2)bean.xml中引入aop名稱空間

複製代碼
<?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">
<bean id="userDao" class="com.juaner.spring.aop.UserDao" />
<bean id="orderDao" class="com.juaner.spring.aop.OrderDao"/>
<bean id="aop" class="com.juaner.spring.aop.Aop"/>
</beans>
複製代碼

2.1註解方式實現aop編程

開啓aop註解

<!--開啓aop註解-->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

使用註解

@Aspect 指定一個類爲切面類

@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))") 指定切入點表達式

@Before("pointCut_()") 前置通知: 目標方法以前執行

@After("pointCut_()") 後置通知:目標方法以後執行(始終執行)

@AfterReturning("pointCut_()") 返回後通知: 執行方法結束前執行(異常不執行)

@AfterThrowing("pointCut_()") 異常通知: 出現異常時候執行

@Around("pointCut_()") 環繞通知: 環繞目標方法執行

@Aspect //指定爲切面類

複製代碼
public class Aop {

//指定切入點表達式,攔截哪些方法,即爲哪些類生成代理對象
@Pointcut("execution(* com.juaner.spring.aop.*.*(..))")
public void testPt_(){

}

@Before("testPt_()")
public void begin(){
System.out.println("事務開始!");
}
@After("testPt_()")
public void commite(){
System.out.println("事務提交!");
}
@AfterReturning("testPt_()")//出現異常不執行
public void afterReturning(){
System.out.println("調用目標方法結束!");
}

@AfterThrowing("testPt_()")//出現異常才執行
public void afterThrowing(){
System.out.println("目標方法出現異常!");
}
@Around("testPt_()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("環繞前");
Object proceed = pjp.proceed();//執行目標方法
System.out.println("環繞後");
}
}
複製代碼

使用切面類

IUserDao userDao = (IUserDao) ac.getBean("userDao");
userDao.save();

若是userDao實現了接口,則userDao爲動態代理對象
不然userDao爲cglib代理對象

2.2使用xml方式實現aop編程

配置切入點

複製代碼
<?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 id="userDao" class="com.juaner.spring.xmlaop.UserDao"></bean>
    <bean id="orderDao" class="com.juaner.spring.xmlaop.OrderDao"/>
    <bean id="aop" class="com.juaner.spring.xmlaop.Aop"></bean>

    <!--aop配置-->
    <aop:config>
        <!--定義一個切入點表達式,攔截哪些方法-->
       <aop:pointcut id="pt" expression="!execution(* com.juaner.spring.xmlaop.OrderDao.*(..))"/>
        <!--切面-->
        <aop:aspect ref="aop">
            <aop:before method="begin" pointcut-ref="pt"/>
            <aop:after method="commite" pointcut-ref="pt"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pt"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>
            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>
    </aop:config>
</beans>
複製代碼

3.切入點表達式

切入點表達式語法定義以下:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
          throws-pattern?)
複製代碼
<?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:p="http://www.springframework.org/schema/p"
    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">
    
    <!-- dao 實例 -->
    <bean id="userDao" class="cn.itcast.g_pointcut.UserDao"></bean>
    <bean id="orderDao" class="cn.itcast.g_pointcut.OrderDao"></bean>
    
    <!-- 切面類 -->
    <bean id="aop" class="cn.itcast.g_pointcut.Aop"></bean>
    
    <!-- Aop配置 -->
    <aop:config>
        
        <!-- 定義一個切入點表達式: 攔截哪些方法 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.*.*(..))" id="pt"/>-->
        
        <!-- 【攔截全部public方法】 -->
        <!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>-->
        
        <!-- 【攔截全部save開頭的方法 】 -->
        <!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>-->
        
        <!-- 【攔截指定類的指定方法, 攔截時候必定要定位到方法】 -->
        <!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>-->
        
        <!-- 【攔截指定類的全部方法】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>-->
        
        <!-- 【攔截指定包,以及其自包下全部類的全部方法】 -->
        <!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>-->
        
        <!-- 【多個表達式】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!-- 下面2個且關係的,沒有意義 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) &amp;&amp; execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) and execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        
        <!-- 【取非值】 -->
        <!--<aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <aop:pointcut expression=" not execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>
        
        <!-- 切面 -->
        <aop:aspect ref="aop">
            <!-- 環繞通知 -->
            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>
    </aop:config>
</beans>    
複製代碼
相關文章
相關標籤/搜索