鍍金池/ 教程/ Java/ Spring AOP+AspectJ注解實(shí)例
Spring EL hello world實(shí)例
Spring使用@Autowired注解自動(dòng)裝配
MapFactoryBean實(shí)例
Bean InitializingBean和DisposableBean實(shí)例
Spring使用@Required注解依賴(lài)檢查
安裝Spring工具套件到Eclipse
CGLIB is required to process @Configuration classes
Spring EL Arrays, Lists, Maps實(shí)例
Spring由類(lèi)型(Type)自動(dòng)裝配
Spring在bean配置文件中定義電子郵件模板
Spring發(fā)送帶附件郵件
ListFactoryBean實(shí)例
Struts 2 + Spring + Hibernate集成實(shí)例
Spring bean引用實(shí)例
Spring JdbcTemplate batchUpdate()實(shí)例
Spring SetFactoryBean實(shí)例
Spring通過(guò)setter方法注入
Spring EL hello world實(shí)例
在bean配置文件中的電子郵件模板
Spring發(fā)送帶附件的Email
Spring EL 方法調(diào)用實(shí)例
Spring自動(dòng)裝配Beans
Spring由構(gòu)造方法自動(dòng)裝配
Spring使用@Required注解依賴(lài)檢查
Spring SimpleJdbcTemplate查詢(xún)示例
自定義@Required-style注解
Spring+JDBC實(shí)例
Spring EL三元運(yùn)算(if-then-else)實(shí)例
JdbcTemplate+JdbcDaoSupport實(shí)例
Spring自動(dòng)掃描組件
Spring EL方法調(diào)用實(shí)例
Spring自動(dòng)裝配Beans
Spring EL bean引用實(shí)例
Spring依賴(lài)注入(DI)
Spring EL Lists,Maps實(shí)例
Spring通過(guò)構(gòu)造方法依賴(lài)注入
通過(guò)MailSender發(fā)送電子郵件
Spring AOP實(shí)例(Pointcut, Advisor)
Spring EL運(yùn)算符實(shí)例
Spring JavaConfig實(shí)例
Spring依賴(lài)注入 (DI)
Spring EL bean引用實(shí)例
Spring由AutoDetect自動(dòng)裝配
Spring由構(gòu)造方法自動(dòng)裝配
Spring JdbcTemplate查詢(xún)實(shí)例
Spring SimpleJdbcTemplate batchUpdate()實(shí)例
Spring+JDBC實(shí)例
如何注入值到Spring bean屬性
Spring SimpleJdbcTemplate類(lèi)命名參數(shù)實(shí)例
Spring PropertyPlaceholderConfigurer實(shí)例
Spring JdbcTemplate batchUpdate() 實(shí)例
Spring EL與ExpressionParser測(cè)試
Spring內(nèi)部Bean實(shí)例
加載多個(gè)Spring bean配置文件
Spring+Hibernate+MySql實(shí)例(注解)
Spring AOP+AspectJ 在XML配置實(shí)例
Spring自動(dòng)代理創(chuàng)建者實(shí)例
Spring EL正則表達(dá)式實(shí)例
測(cè)試 Spring EL與ExpressionParser
java.lang.ClassNotFoundException: org.exolab.castor.xml.XMLExcep
Spring PropertyPlaceholderConfigurer實(shí)例
Spring bean配置繼承
Spring使用Setter依賴(lài)注入
Spring自動(dòng)裝配@Qualifier實(shí)例
Spring依賴(lài)檢查
Spring hello world實(shí)例
Spring依賴(lài)注入servlet會(huì)話監(jiān)聽(tīng)器
Spring自定義@Required-style注解
Spring bean作用域
Spring AOP攔截器的序列
注入值到Spring Bean的屬性
Spring JdbcTemplate+JdbcDaoSupport實(shí)例
Spring教程
Spring自動(dòng)裝配@Qualifier實(shí)例
Spring MapFactoryBean例子
Spring Bean作用域?qū)嵗?/span>
Cannot proxy target class because CGLIB2 is not available
Spring AOP攔截器的順序
Spring集合(List, Set, Map, and Properties)實(shí)例
Spring SimpleJdbcTemplate類(lèi)命名參數(shù)實(shí)例
Spring通過(guò)自動(dòng)檢測(cè)自動(dòng)裝配
Spring+Hibernate+MySql實(shí)例
Spring JavaConfig @Import實(shí)例
訪問(wèn)MessageSource的bean(MessageSourceAware)
Spring JdbcTemplate查詢(xún)實(shí)例
Spring JavaConfig @Import實(shí)例
Spring Object/XML映射實(shí)例
Spring Bean引用例子
Spring AOP+AspectJ注解實(shí)例
java.lang.ClassNotFoundException: org.apache.xml.serialize.XMLSe
Spring依賴(lài)檢查
Spring JavaConfig實(shí)例
Spring AOP+AspectJ注解實(shí)例
Spring bean配置繼承
Spring自動(dòng)掃描組件
自動(dòng)代理創(chuàng)建者實(shí)例
Spring Bean init-method 和 destroy-method實(shí)例
Spring通過(guò)構(gòu)造方法注入
Spring過(guò)濾器組件自動(dòng)掃描
Spring構(gòu)造方法注入類(lèi)型歧義
Spring+JDBC實(shí)例
Spring EL正則表達(dá)式實(shí)例
Spring通過(guò)Gmail SMTP服務(wù)器MailSender發(fā)送電子郵件
Spring AOP+AspectJ在XML配置實(shí)例
SetFactoryBean實(shí)例
Spring注入日期到bean屬性-CustomDateEditor
Spring AOP通知實(shí)例 – Advice
Spring使用@Autowired注解自動(dòng)裝配
Spring AOP實(shí)例(Pointcut,Advisor)
Spring AOP在Hibernate的事務(wù)管理
Spring初學(xué)快速入門(mén)
Spring內(nèi)部bean實(shí)例
Spring bean加載多個(gè)配置文件
Spring + Hibernate+ MySql注解實(shí)例
Spring @PostConstruct和@PreDestroy實(shí)例
Spring依賴(lài)注入servlet會(huì)話監(jiān)聽(tīng)器
Spring ListFactoryBean實(shí)例
Spring松耦合的實(shí)例
Spring過(guò)濾器組件自動(dòng)掃描
Spring按名稱(chēng)(Name)自動(dòng)裝配
Spring AOP通知實(shí)例(Advice)
Spring AOP在Hibernate事務(wù)管理
Bean init-method和destroy-method實(shí)例
Spring EL操作符實(shí)例
Spring注入日期到bean屬性(CustomDateEditor)
資源加載程序的getResource()示例
Bean @PostConstruct和@PreDestroy實(shí)例
Struts2+Spring集成實(shí)例
Spring集合 (List,Set,Map,Properties) 實(shí)例
Spring按類(lèi)型(Type)自動(dòng)裝配
Spring由名稱(chēng)(Name)自動(dòng)裝配
Spring SimpleJdbcTemplate batchUpdate()實(shí)例
Spring hello world實(shí)例
Spring Bean InitializingBean和DisposableBean實(shí)例
Spring構(gòu)造方法注入類(lèi)型歧義
Spring EL三元操作符(if-then-else)實(shí)例
Spring+Hibernate+MySql實(shí)例
Spring松耦合實(shí)例

Spring AOP+AspectJ注解實(shí)例

在本教程中,我們將向你展示如何將AspectJ注解集成到Spring AOP框架。在這個(gè)Spring AOP+ AspectJ 示例中,讓您輕松實(shí)現(xiàn)攔截方法。
常見(jiàn)AspectJ的注解:
  1. @Before – 方法執(zhí)行前運(yùn)行
  2. @After – 運(yùn)行在方法返回結(jié)果后
  3. @AfterReturning – 運(yùn)行在方法返回一個(gè)結(jié)果后,在攔截器返回結(jié)果。
  4. @AfterThrowing – 運(yùn)行方法在拋出異常后,
  5. @Around – 圍繞方法執(zhí)行運(yùn)行,結(jié)合以上這三個(gè)通知。
注意
Spring AOP 中沒(méi)有 AspectJ 支持,請(qǐng)閱讀 內(nèi)置 Spring AOP 例子。

1. 目錄結(jié)構(gòu)

看到這個(gè)例子的目錄結(jié)構(gòu)。

2. Spring Beans

普通 bean 中有幾個(gè)方法,后來(lái)通過(guò) AspectJ 注解攔截。
package com.yiibai.customer.bo;

public interface CustomerBo {

	void addCustomer();
	
	String addCustomerReturnValue();
	
	void addCustomerThrowException() throws Exception;
	
	void addCustomerAround(String name);
}
package com.yiibai.customer.bo.impl;

import com.yiibai.customer.bo.CustomerBo;

public class CustomerBoImpl implements CustomerBo {

	public void addCustomer(){
		System.out.println("addCustomer() is running ");
	}
	
	public String addCustomerReturnValue(){
		System.out.println("addCustomerReturnValue() is running ");
		return "abc";
	}
	
	public void addCustomerThrowException() throws Exception {
		System.out.println("addCustomerThrowException() is running ");
		throw new Exception("Generic Error");
	}
	
	public void addCustomerAround(String name){
		System.out.println("addCustomerAround() is running, args : " + name);
	}
}

4. 啟用AspectJ

在 Spring 配置文件,把“<aop:aspectj-autoproxy />”,并定義Aspect(攔截)和普通的bean。

File : applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

	<aop:aspectj-autoproxy />

	<bean id="customerBo" class="com.yiibai.customer.bo.impl.CustomerBoImpl" />

	<!-- Aspect -->
	<bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" />

</beans>

4. AspectJ @Before

在下面例子中,logBefore()方法將在 customerBo接口的 addCustomer()方法的執(zhí)行之前被執(zhí)行。
AspectJ的“切入點(diǎn)”是用來(lái)聲明哪種方法將被攔截,應(yīng)該參考Spring AOP切入點(diǎn)指南,支持切入點(diǎn)表達(dá)式的完整列表。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

	@Before("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
	public void logBefore(JoinYiibai joinYiibai) {

		System.out.println("logBefore() is running!");
		System.out.println("hijacked : " + joinYiibai.getSignature().getName());
		System.out.println("******");
	}

}

運(yùn)行

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomer();

輸出結(jié)果

logBefore() is running!
hijacked : addCustomer
******
addCustomer() is running

5. AspectJ @After

在下面例子中,logAfter()方法將在 customerBo 接口的 addCustomer()方法的執(zhí)行之后執(zhí)行。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {

	@After("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
	public void logAfter(JoinYiibai joinYiibai) {

		System.out.println("logAfter() is running!");
		System.out.println("hijacked : " + joinYiibai.getSignature().getName());
		System.out.println("******");

	}

}

運(yùn)行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomer();

輸出結(jié)果

addCustomer() is running 
logAfter() is running!
hijacked : addCustomer
******

6. AspectJ @AfterReturning

在下面例子中,logAfterReturning()方法將在 customerBo 接口的addCustomerReturnValue()方法執(zhí)行之后執(zhí)行。此外,還可以截取返回的值使用“returning”屬性。

要截取返回的值,對(duì)“returning”屬性(結(jié)果)的值必須用相同的方法參數(shù)(結(jié)果)。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

   @AfterReturning(
      pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))",
      returning= "result")
   public void logAfterReturning(JoinYiibai joinYiibai, Object result) {

	System.out.println("logAfterReturning() is running!");
	System.out.println("hijacked : " + joinYiibai.getSignature().getName());
	System.out.println("Method returned value is : " + result);
	System.out.println("******");
   }
}

運(yùn)行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomerReturnValue();

輸出結(jié)果

addCustomerReturnValue() is running 
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
******

7. AspectJ @AfterReturning

在下面的例子中,如果 customerBo 接口的addCustomerThrowException()方法拋出異常logAfterThrowing()方法將被執(zhí)行。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class LoggingAspect {

   @AfterThrowing(
      pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))",
      throwing= "error")
    public void logAfterThrowing(JoinYiibai joinYiibai, Throwable error) {

	System.out.println("logAfterThrowing() is running!");
	System.out.println("hijacked : " + joinYiibai.getSignature().getName());
	System.out.println("Exception : " + error);
	System.out.println("******");

    }
}

運(yùn)行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerThrowException();

輸出結(jié)果

addCustomerThrowException() is running 
logAfterThrowing() is running!
hijacked : addCustomerThrowException
Exception : java.lang.Exception: Generic Error
******
Exception in thread "main" java.lang.Exception: Generic Error
	//...

8. AspectJ @Around

在下面例子中,logAround()方法將在customerBo接口的addCustomerAround()方法執(zhí)行之前執(zhí)行, 必須定義“joinYiibai.proceed();” 控制何時(shí)攔截器返回控制到原來(lái)的addCustomerAround()方法。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.ProceedingJoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;

@Aspect
public class LoggingAspect {

   @Around("execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))")
   public void logAround(ProceedingJoinYiibai joinYiibai) throws Throwable {

	System.out.println("logAround() is running!");
	System.out.println("hijacked method : " + joinYiibai.getSignature().getName());
	System.out.println("hijacked arguments : " + Arrays.toString(joinYiibai.getArgs()));
		
	System.out.println("Around before is running!");
	joinYiibai.proceed(); //continue on the intercepted method
	System.out.println("Around after is running!");
		
	System.out.println("******");

   }
	
}

運(yùn)行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerAround("yiibai");

輸出結(jié)果

logAround() is running!
hijacked method : addCustomerAround
hijacked arguments : [yiibai]
Around before is running!
addCustomerAround() is running, args : yiibai
Around after is running!
******

總結(jié)

它總是建議采用最少 AspectJ 注解。這是關(guān)于Spring AspectJ 的一篇相當(dāng)長(zhǎng)的文章。進(jìn)一步的解釋和例子,請(qǐng)?jiān)L問(wèn)下面的參考鏈接。

下載源代碼 – http://pan.baidu.com/s/1boo4f9P