1. 程式人生 > >使用Spring配置文件實現AOP

使用Spring配置文件實現AOP

result 第一個 .com targe 細節 cat xsd 修改 描述

使用Spring配置文件實現AOP

前面我們已經學會了使用Spring的註解方式實現AOP,現在我們就要學習使用Spring配置文件實現AOP。本文是建立在使用Spring的註解方式實現AOP的細節的案例的基礎之上的。
我們首先將MyInterceptor類的代碼修改為:

/**
 * 切面
 * @author li ayun
 *
 */
@Aspect
public class MyInterceptor {
    public void doAccessCheck() {
        System.out.println("前置通知");
    }

    public void doAfterReturning() { 
        System.out.println("後置通知");
    }

    public void doAfter() {
        System.out.println("最終通知");
    }

    public void doAfterThrowing() {
        System.out.println("異常通知");
    }

    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("進入方法");
        Object result = pjp.proceed();
        System.out.println("退出方法");
        return result;
    }

}
  • 1
  • 2

從上可知MyInterceptor不過就是一個普通的JavaBean。現在若要使用Spring配置文件實現AOP,則須將Spring配置文件的內容修改為:

<?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-4.2.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <aop:aspectj-autoproxy />
    <bean id="personService" class="cn.itcast.service.impl.PersonServiceImpl"></bean>
    <bean id="aspetbean" class="cn.itcast.service.MyInterceptor"></bean>
    <aop:config>
        <aop:aspect id="asp" ref="aspetbean">
            <aop:pointcut expression="execution(* cn.itcast.service.impl.PersonServiceImpl.*(..))" id="mycut"/> 
            <aop:before pointcut-ref="mycut" method="doAccessCheck"/>
            <aop:after-returning pointcut-ref="mycut" method="doAfterReturning"/>
            <aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/>
            <aop:after pointcut-ref="mycut" method="doAfter"/>
            <aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
        </aop:aspect>
    </aop:config>
</beans>
  • 1

如果PersonServiceImpl類的代碼為:

public class PersonServiceImpl implements PersonService {

    @Override
    public void save(String name) {
        // throw new RuntimeException("我是異常");
        System.out.println("我是save()方法");
    }

    @Override
    public void update(String name, Integer id) {
        System.out.println("我是update()方法");
    }

    @Override
    public String getPersonName(Integer id) {
        System.out.println("我是getPersonName()方法");
        return "xxx";
    }

}
  • 1

那麽除了異常通知外,其他通知都將會執行。此時,測試SpringAOPTest類的interceptorTest()方法,會發現Eclipse控制臺打印:
技術分享
如果PersonServiceImpl類的代碼為:

public class PersonServiceImpl implements PersonService {

    @Override
    public void save(String name) {
        throw new RuntimeException("我是異常");
        // System.out.println("我是save()方法");
    }

    @Override
    public void update(String name, Integer id) {
        System.out.println("我是update()方法");
    }

    @Override
    public String getPersonName(Integer id) {
        System.out.println("我是getPersonName()方法");
        return "xxx";
    }

}
  • 1

那麽,異常通知就會被執行。此時,測試SpringAOPTest類的interceptorTest()方法,會發現Eclipse控制臺打印:
技術分享
並且還拋出異常。
基於Spring配置文件實現AOP,我們就學習到這裏。如要查看源碼,可點擊使用Spring配置文件實現AOP進行下載。

aspectj的切入點語法定義細節

在使用Spring的註解方式實現AOP入門一文中,我們就初步了解了一下aspectj的切入點語法。我們可利用方法簽名來編寫aspectj的切入點表達式。最典型的切入點表達式是根據方法的簽名來匹配各種方法:

  • execution (* cn.itcast.service.impl.PersonServiceImpl.*(..)):匹配PersonServiceImpl類中聲明的所有方法。第一個*代表任意修飾符及任意返回值類型,第二個*代表任意方法,..匹配任意數量任意類型的參數,若目標類與該切面在同一個包中,可以省略包名。
  • execution public * cn.itcast.service.impl.PersonServiceImpl.*(..):匹配PersonServiceImpl類中的所有公有方法。
  • execution public double cn.itcast.service.impl.PersonServiceImpl.*(..):匹配PersonServiceImpl類中返回值類型為double類型的所有公有方法。
  • execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, ..):匹配PersonServiceImpl類中第一個參數為double類型,後面不管有無參數的所有公有方法,並且該方法的返回值類型為double類型。
  • execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, double):匹配PersonServiceImpl類中參數類型為double,double類型的,並且返回值類型也為double類型的所有公有方法。

現在若要求只攔截PersonServiceImpl類中返回值類型為String的方法,則aspectj的切入點表達式應該這樣寫:

execution(java.lang.String cn.itcast.service.impl.PersonServiceImpl.*(..))
  • 1
  • 1

若要求攔截PersonServiceImpl類中輸入參數中的第一個參數類型為String,後面不管有沒有參數的方法,則aspectj的切入點表達式應該這樣寫:

execution(* cn.itcast.service.impl.PersonServiceImpl.*(java.lang.String, ..))

若要求攔截PersonServiceImpl類中返回值類型不是void的所有方法,則aspectj的切入點表達式應該這樣寫:

execution(!void cn.itcast.service.impl.PersonServiceImpl.*(..))

若要求攔截cn.itcast.service包及其子包下的所有類的所有方法,則aspectj的切入點表達式應該這樣寫:

execution(* cn.itcast.service..*.*(..))

使用Spring配置文件實現AOP