1. 程式人生 > >springAOP前置增強、後置增強、環繞增強(程式設計式)

springAOP前置增強、後置增強、環繞增強(程式設計式)

Spring AOP的幾個概念

1.切面(Aspect):切面就是一個關注點的模組化,如事務管理、日誌管理、許可權管理等; 
2.連線點(Joinpoint):程式執行時的某個特定的點,在Spring中就是一個方法的執行; 
3.通知(Advice):通知就是在切面的某個連線點上執行的操作,也就是事務管理、日誌管理等; 
4.切入點(Pointcut):切入點就是描述某一類選定的連線點,也就是指定某一類要織入通知的方法; 
5.目標物件(Target):就是被AOP動態代理的目標物件; 

藉助下圖進行理解:


先來了解切面程式設計的使用

前置增強

建立一個前置增強類

package cjq.demo.spring.aop;

import
org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /** * author: cjianquan * date: 2016/9/9 */ public class GreetingBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("GreetingBeforeAdvice Before"
); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

後置增強

package cjq.demo.spring.aop;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

/**
 * author: cjianquan
 * date: 2016/9/9
 */
public class GreetingAfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning
(Object result, Method method, Object[] args, Object target) throws Throwable { System.out.println("GreetingAfterAdvice After"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

測試程式碼:

    @Test
    public void test_springAop(){
        ProxyFactory proxyFactory = new ProxyFactory();     // 建立代理工廠
        proxyFactory.setTarget(new GreetingImpl());         // 射入目標類物件
        proxyFactory.addAdvice(new GreetingBeforeAdvice()); // 新增前置增強
        proxyFactory.addAdvice(new GreetingAfterAdvice());  // 新增後置增強

        Greeting greeting = (Greeting) proxyFactory.getProxy(); // 從代理工廠中獲取代理
        greeting.sayHello("Jack");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

當然,我們完全可以只定義一個增強類,讓它同時實現 MethodBeforeAdvice 與 AfterReturningAdvice 這兩個介面,如下

package cjq.demo.spring.aop;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

/**
 * author: cjianquan
 * date: 2016/9/9
 */
public class GreetingBeforeAndAfterAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(" GreetingBeforeAndAfterAdvice  Before");
    }

    @Override
    public void afterReturning(Object result, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("GreetingBeforeAndAfterAdvice  After");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

測試程式碼:

    @Test
    public void test_springAop1(){
        ProxyFactory proxyFactory = new ProxyFactory();     // 建立代理工廠
        proxyFactory.setTarget(new GreetingImpl());         // 射入目標類物件
        proxyFactory.addAdvice(new GreetingBeforeAndAfterAdvice()); // 新增增強

        Greeting greeting = (Greeting) proxyFactory.getProxy(); // 從代理工廠中獲取代理
        greeting.sayHello("Jack");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

環繞增強

package cjq.demo.spring.aop;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;

/**
 * author: cjianquan
 * date: 2016/9/9
 */
@Component("greetingAroundAdvice")
public class GreetingAroundAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        before();
        Object result = invocation.proceed();
        after();
        return result;
    }

    private void before() {
        System.out.println("GreetingAroundAdvice  Before");
    }

    private void after() {
        System.out.println("GreetingAroundAdvice  After");
    }
}
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  6.     <beanid="greetingBefore"class="com.jike.spring.chapter10.aop.advice.WaiterBeforeAdvice"/>
  7.     <beanid="greetingAfter"class="com.jike.spring.chapter10.aop.advice.WaiterAfterAdvice"/>
  8.     <beanid="greetingAround"class="com.jike.spring.chapter10.aop.advice.WaiterAroundAdvice"/>
  9.     <beanid="target"class="com.jike.spring.chapter10.aop.advice.NativeWaiter"/>
  10.     <beanid="waiter"class="org.springframework.aop.framework.ProxyFactoryBean"
  11.         p:proxyInterfaces="com.jike.spring.chapter10.aop.advice.Waiter"
  12.         p:target-ref="target"p:interceptorNames="greetingAround"/>
  13. </beans>

測試程式碼:

    @Test
    public void test_greetingAroundAdvice(){
        ProxyFactory proxyFactory = new ProxyFactory();     // 建立代理工廠
        proxyFactory.setTarget(new GreetingImpl());         // 射入目標類物件
        proxyFactory.addAdvice(new GreetingAroundAdvice()); // 新增增強

        Greeting greeting = (Greeting) proxyFactory.getProxy(); // 從代理工廠中獲取代理
        greeting.sayHello("Jack");
    }
  • 1