Spring框架的AOP編程,最通俗的語言解釋,易懂易學


第七章:AOP技術

前言:

AOP技術是根據動態代理設計模式進行的技術。動態代理技術分jdk動態代理和cglib動態代理

jdk動態代理特點:

(1)繼承java.lang.reflect.proxy類

(2)實現了真實類實現的接口

(3)真實類和代理類之間的關系是:他們都實現了相同的接口

cglib動態代理特點:

特點:

(1)代理類是真實類的子類

注:本片文章主要理解AOP編程,至於動態代理技術不做過多介紹,有需要的話,可以留言,下篇文章可以進行講解。

7.1:AOP原理概述

AOP:Aspect  Oriented  Programming,面向切面編程

傳統形式,web項目執行流程:

缺點:

(1)Bad  Smell現象,指一些代碼邏輯出現了在了不合適的層次。

例如:在service層有數據庫的事務處理代碼,不合乎規范

改進:

AOP編程:

本質上,屬於動態代理設計模式

切面編程:類似於在鏈式程序指定流程中,在service層處進行截斷,此處的斷層成為切面,此處的service處的程序運行為豎向,可以看作service層的強化操作。

概念:

(1)Point(切點):表示要對哪個方法進行增強

(2)Advice(通知):表示額外增加的功能

(3)Aspect(切面):就是代理對象,(切面+切點)

(4)Weaving(織入):將通知添加到切點中的操作,生成動態代理的過程

 

7.2:AOP實現過程

7.2.1:導包

1. 日志包:

   commons-logging.jar

2. Spring核心包:

       spring-core.jar

       spring-beans.jar

       spring-context.jar

       spring-expression.jar

3. aop依賴的jar包:

       spring-aop.jar

       aopalliance.jar -aop聯盟提供的對aop的具體實現

7.2.2:測試用的service代碼

spring支持兩種動態代理的實現:

(1)如果提供了接口,就用jdk動態代理

(2)如果沒有提供接口,就用cglib動態代理

7.2.3:提供通知

spring中的通知類型:

(1)前置通知:在切點方法調用前操作,MethodBeforeAdvice

(2)后置操作:在切點方法掉用后操作,AfterReturningAdvice

(3)異常通知:在切點方法執行發生異常時執行,ThrowsAdvice

(4)環繞通知:包含了前置通知、后置通知和異常通知,MethodInterceptor

public class DemoBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("我是前置通知....");
    }
}

  

7.2.4:配置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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置service對象-->
    <bean id="userService" class="com.bjsxt.service.impl.UserServiceImpl" />
    <bean id="testService" class="com.bjsxt.service.TestService" />
    <!--配置通知對象-->
    <bean id="demoBefore" class="com.bjsxt.advice.DemoBeforeAdvice" />
    <!--配置織入, 生成動態代理-->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!--配置目標對象-->
        <property name="targetName" value="userService" />
        <!--配置通知-->
        <property name="interceptorNames">
            <array>
                <value>demoBefore</value>
            </array>
        </property>
    </bean>
    <bean id="testProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="targetName" value="testService" />
        <property name="interceptorNames">
            <array>
                <value>demoBefore</value>
            </array>
        </property>
    </bean>
</beans>

  

7.2.5:測試代碼

public class TestAOP {
    @Test
    public void testAop2() {
        //cglib動態代理
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        TestService testProxy = context.getBean("testProxy", TestService.class);
        System.out.println(testProxy.getClass().getName());
        System.out.println(testProxy.getClass().getSuperclass().getName());
        testProxy.test();
    }

    @Test
    public void testAop() {
        //jdk動態代理
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = context.getBean("proxy", UserService.class);
        System.out.println(userService.getClass().getName());
        userService.demo();
    }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM