Spring教程 - Spring AOP

2018-01-09 19:06 更新

Spring教程 - Spring AOP


除了依賴注入(DI),Spring Framework提供的另一個核心特性是面向方面的編程(AOP)。

除了依賴注入(DI),Spring Framework提供的另一個核心特性是面向方面的編程(AOP)。...

橫切關(guān)注點指的是應(yīng)用程序中的邏輯不能從其余的分解應(yīng)用程序并可能導(dǎo)致代碼重復(fù)和緊密耦合。

AOP是一個旨在提高模塊性的編程范例通過允許分離交叉關(guān)注點。

AOP是一個旨在提高模塊性的編程范例通過允許分離交叉關(guān)注點。...

Spring AOP框架在各方面模塊化橫切關(guān)注點。當(dāng)在Spring IoC容器中執(zhí)行一個方法時,Spring AOP可以劫持執(zhí)行方法,并在方法執(zhí)行之前或之后添加額外的功能。



AOP概念

AOP具有自己特定的概念和術(shù)語集。

以下是AOP的核心概念:

  • Joinpoints is a point during the execution of your application. Typical example of joinpoints is a call to a method. Joinpoints define the points in your application at which you can insert additional logic using AOP.
  • Advice is the code executed at a particular joinpoint. There are many types of advice, such as before , which executes before the joinpoint, and after , which executes after it.
  • Pointcut is a collection of joinpoints that is used to define when advice should be executed. By creating pointcuts, we control over how to apply advice to the Java Bean in the application.
  • Weaving is the process of inserting aspects into the application code at the appropriate point.
  • An object whose execution flow is modified by an AOP process is referred to as the target object or advised object.

Spring AOP有四種類型的建議。

  • Before advice - Run before the method execution
  • After returning advice - Run after the method returns a result
  • After throwing advice - Run after the method throws an exception
  • Around advice - Run around the method execution, combine all three advices above.

建議是在方法執(zhí)行之前或之后采取的動作。



依賴

將以下新的依賴關(guān)系添加到POM.xml中進(jìn)行AOP編碼。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

Java Bean

以下代碼定義了打印機(jī)服務(wù)的Java bean。

package com.hgci.cnmon;

public class PrinterService {
  private String name;
  private String url;
  public void setName(String name) {
    this.name = name;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public void printName() {
    System.out.println("Printer Name : " + this.name);
  }
  public void printURL() {
    System.out.println("Printer URL : " + this.url);
  }
  public void printThrowException() {
    throw new IllegalArgumentException();
  }
}

XML配置

這里是用于bean配置的Spring-Customer.xml文件。

<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-2.5.xsd">
  <bean id="myService" class="com.hgci.cnmon.PrinterService">
    <property name="name" value="printerName" />
    <property name="url" value="http://www.hgci.cn" />
  </bean>
</beans>

以下是運行上面代碼的主類。

package com.hgci.cnmon;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    ApplicationContext appContext = new ClassPathXmlApplicationContext(
        new String[] { "SpringBeans.xml" });
    PrinterService cust = (PrinterService) appContext.getBean("myService");
    cust.printName();
    cust.printURL();
    try {
      cust.printThrowException();
    } catch (Exception e) {
    }
  }
}

輸出


Download Java2s_Spring_Pre_AOP.zip

XML配置...

下面的代碼顯示了如何添加Before通知。

A Before在方法執(zhí)行之前執(zhí)行。

首先,創(chuàng)建一個實現(xiàn)MethodBeforeAdvice接口的類。

package com.hgci.cnmon;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class AOPBeforeMethod implements MethodBeforeAdvice
{
  @Override
  public void before(Method method, Object[] args, Object target)
    throws Throwable {
          System.out.println("AOPBeforeMethod : Before method call.");
  }
}

然后,我們在xml配置文件中創(chuàng)建AOPBeforeMethod bean。

<bean id="aopBeforeMethodBean" class="com.java2s.aop.AOPBeforeMethod" />

要使用 AOPBeforeMethod 類,我們必須使用安裝它 org.springframework.aop.framework.ProxyFactoryBean ,如下所示。

  <bean id="myServiceProxy" 
                 class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="myService" />

    <property name="interceptorNames">
      <list>
        <value>aopBeforeMethodBean</value>
      </list>
    </property>
  </bean>

完整的源代碼

<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-2.5.xsd">

  <bean id="myService" class="com.hgci.cnmon.PrinterService">
    <property name="name" value="printerName" />
    <property name="url" value="http://www.hgci.cn" />
  </bean>

  <bean id="aopBeforeMethodBean" class="com.hgci.cnmon.AOPBeforeMethod" />

  <bean id="myServiceProxy" 
                 class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="myService" />

    <property name="interceptorNames">
      <list>
        <value>aopBeforeMethodBean</value>
      </list>
    </property>
  </bean>
</beans>

再次運行main函數(shù)。

從結(jié)果我們可以看到AOPBeforeMethod“的before()方法在每個myService的方法之前執(zhí)行。

返回建議后

下面的代碼顯示了如何使用After返回通知。返回通知后,將在方法返回結(jié)果后執(zhí)行。

首先,創(chuàng)建一個實現(xiàn)AfterReturningAdvice接口的類。

package com.hgci.cnmon;

import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class AOPAfterMethod implements AfterReturningAdvice
{
  @Override
  public void afterReturning(Object returnValue, Method method,
    Object[] args, Object target) throws Throwable {
          System.out.println("AOPAfterMethod : After method call.");
  }
}

然后,在 AOPAfterMethod 類中安裝Bean配置文件。

<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-2.5.xsd">

  <bean id="myService" class="com.hgci.cnmon.PrinterService">
    <property name="name" value="printerName" />
    <property name="url" value="http://www.hgci.cn" />
  </bean>

  <bean id="aopAfterMethodBean" class="com.hgci.cnmon.AOPAfterMethod" />

  <bean id="myServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="myService" />

    <property name="interceptorNames">
      <list>
        <value>aopAfterMethodBean</value>
      </list>
    </property>
  </bean>
</beans>

再次運行main函數(shù)。 這里是輸出。

從結(jié)果我們可以看到AOPAfterMethod的“afterReturning()方法在每個myService的方法返回結(jié)果之后執(zhí)行。

投擲后建議

下面的代碼顯示了如何使用After拋出的建議。拋出后拋出的通知會在方法拋出異常后執(zhí)行。

第一,創(chuàng)建一個實現(xiàn)ThrowsAdvice接口的類,并創(chuàng)建一個afterThrowing方法來劫持IllegalArgumentException異常。

package com.hgci.cnmon;

import org.springframework.aop.ThrowsAdvice;

public class AOPThrowException implements ThrowsAdvice {
  public void afterThrowing(IllegalArgumentException e) throws Throwable {
    System.out.println("AOPThrowException : Throw exception call.");
  }
}

然后,在Bean配置文件中安裝 AOPThrowException 。

<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-2.5.xsd">

  <bean id="myService" class="com.hgci.cnmon.PrinterService">
    <property name="name" value="printerName" />
    <property name="url" value="http://www.hgci.cn" />
  </bean>

  <bean id="aopThrowExceptionBean" class="com.hgci.cnmon.AOPThrowException" />

  <bean id="myServiceProxy" 
                 class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="myService" />

    <property name="interceptorNames">
      <list>
        <value>aopThrowExceptionBean</value>
      </list>
    </property>
  </bean>
</beans>

運行代碼,這里是輸出。

Printer Name : printerName
Printer URL : http://www.hgci.cn
AOPThrowException : Throw exception call.

從結(jié)果我們可以看到Spring IoC容器運行AOPThrowException的s afterThrowing()  方法,當(dāng)myService的方法拋出異常。

周圍的建議

以下代碼顯示如何使用Around建議。周圍的建議綜合了上面的所有三個建議,并在方法執(zhí)行期間執(zhí)行。

首先,創(chuàng)建一個實現(xiàn)MethodInterceptor接口的類。

public Object invoke(MethodInvocation methodInvocation)throws Throwable方法是為每個方法調(diào)用,我們必須調(diào)用“methodInvocation.proceed();" 以運行原始方法,否則原方法將不會運行。

package com.hgci.cnmon;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class AOPAroundMethod implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {

    System.out.println("Method name : "
        + methodInvocation.getMethod().getName());
    System.out.println("Method arguments : "
        + Arrays.toString(methodInvocation.getArguments()));

    System.out.println("AOPAroundMethod : Before method call.");

    try {
      // proceed to original method call
      Object result = methodInvocation.proceed();

      // same with AfterReturningAdvice
      System.out.println("AOPAroundMethod : after call.");

      return result;

    } catch (IllegalArgumentException e) {
      System.out.println("AOPAroundMethod : Throw exception call.");
      throw e;
    }
  }
}

這里是xml Bean配置文件來安裝Around Advice AOP。

<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-2.5.xsd">

  <bean id="myService" class="com.hgci.cnmon.PrinterService">
    <property name="name" value="printerName" />
    <property name="url" value="http://www.hgci.cn" />
  </bean>

  <bean id="aopAroundMethodBean" class="com.hgci.cnmon.AOPAroundMethod" />

  <bean id="myServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="myService" />

    <property name="interceptorNames">
      <list>
        <value>aopAroundMethodBean</value>
      </list>
    </property>
  </bean>
</beans>

運行main函數(shù),這里是輸出。


Download AOP_Around.zip
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號