基於@AspectJ和schema的aop(一)

來源:互聯網
上載者:User

標籤:location   聯合   servet   ack   aspectj   目標   stat   不同   exe   

  在前面我們使用Pointcut和Advice描述切點和增強, 並使用Advisor整合兩者描述切面[email protected]使用註解來描述切點和增強.兩者使用的方式不同, 但是在本質上都是一樣的.

  我們還是用以前的例子來舉例, 學習如何使用@AspectJ來描述切點和增強.首先看一個簡單的例子.

package com.bao.bao.aspectj;/** * Created by xinfengyao on 16-10-23. */public interface Waiter {    public void greetTo(String clientName);    public void serveTo(String clientName);}
package com.bao.bao.aspectj;/** * Created by xinfengyao on 16-10-23. */public class NaiveWaiter implements Waiter {    @Override    public void greetTo(String clientName) {        System.out.println("NaiveWaiter greetTo " + clientName + "...");    }    @Override    public void serveTo(String clientName) {        System.out.println("NaiveWaiter serveTo " + clientName + "...");    }}

  下面我們使用AspectJ定義一個切面

package com.bao.bao.aspectj;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;/** * Created by xinfengyao on 16-10-23. */@Aspectpublic class PreGreetingAspect {    @Before("execution(* greetTo(..))")    public void beforeGreeting() {        System.out.println("Here are you!");    }}

  我們發現, 這個類沒用實現任何特殊的介面, 只是一個普通的POJO, 特殊之處是使用了@AspectJ註解.

  首先在PreGreetingAspect上面標註了@Aspect的註解, 第三方程式就可以使用這個註解來判斷某個類是否是一個切面;其次, 我們在beforeGreeting()方法上面標註了註解@Before, 並提供了參數execution(*greetTo(..), 這個註解提供了兩個資訊, @Before註解表示該增強是一個前置增強,而成員值是一個AspectJ運算式, 含義是:在目標類的greetTo()方法上織入增強, greetTo()方法可以帶任意的入參和返回任意值;最後在beforeGreeting()方法中定義的就是增強邏輯, 該橫切邏輯在目標方法前調用.

  PreGreetingAspect通過註解, 將切點, 增強類型和增強邏輯糅合在一起, 是切面的定義渾然天成.PreGreetingAspect就相當於我們之前定義的BeforeAdvice, NameMatchMethodPointcut以及DefaultPointcutAdvisor聯合表達的資訊.

  下面我們通過org.springframework.aop.aspectj.annotation.AspectJProxyFactory為NaiveWaiter產生織入PreGreetingAspect切面的代理.

package com.bao.bao.aspectj;import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;/** * Created by xinfengyao on 16-10-23. */public class AspectJProxyTest {    public static void main(String[] args) {        AspectJProxyFactory proxyFactory = new AspectJProxyFactory();        Waiter target = new NaiveWaiter();        proxyFactory.setTarget(target);        proxyFactory.addAspect(PreGreetingAspect.class);        Waiter proxy = proxyFactory.getProxy();        proxy.greetTo("tom");        proxy.serveTo("marry");    }}

  運行結果:

Here are you!NaiveWaiter greetTo tom...NaiveWaiter serveTo marry...

  通過輸出資訊我們可以看到, 代理對象的greetTo()方法已經織入了切面類所定義的橫切邏輯.

  雖然可以通過編程的方式織入切面, 但一般都是通過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"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="waiter" class="com.bao.bao.aspectj.NaiveWaiter"/>    <bean class="com.bao.bao.aspectj.PreGreetingAspect"/>        <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/></beans>

  在前面我們介紹過兩種自動代理建立器, AnnotationAwareAspectJAutoProxyCreator能夠將@AspectJ註解的切面自動織入到目標bean中.

  如果使用基於schema的aop命名空間進行配置就更簡單了.

    <bean id="waiter" class="com.bao.bao.aspectj.NaiveWaiter"/>    <bean class="com.bao.bao.aspectj.PreGreetingAspect"/>    <aop:aspectj-autoproxy/>

  通過aop命名空間的<aop:aspectj-autoproxy/>自動為spring容器中的那些匹配@AspectJ切面的bean自動建立代理, 完成切面織入.其實spring在內部的原理還是使用AnnotationAwareAspectJAutoProxyCreator進行自動代理的建立工作.

基於@AspectJ和schema的aop(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.