部分例子摘自 spring in action
(1)使用ProxyFactoryBean的代理
package chapter4; public interface Performable { public void perform() throws Exception; } package chapter4; import java.util.Random; public class Artist implements Performable { public void perform() throws Exception { int num = new Random().nextInt(100); if(num >= 50) { throw new Exception(String.valueOf(num)); } else { System.out.println(num); } } } package chapter4; public class Audience { public Audience() { } public void takeSeats() { System.out.println("The audience is taking their seats."); } public void turnOffCellPhones() { System.out.println("The audience is turning off " + "their cellphones"); } public void applaud() { System.out.println("CLAP CLAP CLAP CLAP CLAP"); } public void demandRefund() { System.out.println("Boo! We want our money back!"); } } package chapter4; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.ThrowsAdvice; public class AudienceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice { private Audience audience; public void setAudience(Audience audience) { this.audience = audience; } public void before(Method method, Object[] args, Object target) throws Throwable { audience.takeSeats(); audience.turnOffCellPhones(); } public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { audience.applaud(); } public void afterThrowing(Exception ex) { audience.demandRefund(); } }
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="audience" class="chapter4.Audience" /> <bean id="audienceAdvice" class="chapter4.AudienceAdvice" > <property name="audience" ref="audience" /> </bean> <bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="advice" ref="audienceAdvice" /> <property name="expression" value="execution(* *.perform(..))" /> </bean> <bean id="artistTarget" class="chapter4.Artist" /> <bean id="artist" class="org.springframework.aop.framework.ProxyFactoryBean" > <property name="target" ref="artistTarget" /> <property name="interceptorNames" value="audienceAdvisor" /> <property name="proxyInterfaces" value="chapter4.Performable" /> </bean> </beans>
(2)隐式使用ProxyFactoryBean的aop代理
DefaultAdvisorAutoProxyCreator实现了BeanPostProcessor,它将自动检查advisor的pointcut是否匹配bean的方法,如果匹配会替换bean为一个proxy,并且应用其advice。
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" /> <bean id="audience" class="chapter4.Audience" /> <bean id="audienceAdvice" class="chapter4.AudienceAdvice" > <property name="audience" ref="audience" /> </bean> <bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="advice" ref="audienceAdvice" /> <property name="expression" value="execution(* *.perform(..))" /> </bean> <bean id="artist" class="chapter4.Artist" /> </beans>
(3)使用注解的aop代理
xml中增加了一个<aop:aspectj-autoproxy />,它创建了AnnotationAwareAspectJAutoProxyCreator在spring中,这个类将自动代理匹配的类的放方法。和上个例子中DefaultAdvisorAutoProxyCreator做同样的工作。
package chapter4; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class Audience { public Audience() { } @Pointcut("execution(* *.perform(..))") public void pointcut(){} @Before("pointcut()") public void takeSeats() { System.out.println("The audience is taking their seats."); } @Before("pointcut()") public void turnOffCellPhones() { System.out.println("The audience is turning off " + "their cellphones"); } @AfterReturning("pointcut()") public void applaud() { System.out.println("CLAP CLAP CLAP CLAP CLAP"); } @AfterThrowing("pointcut()") public void demandRefund() { System.out.println("Boo! We want our money back!"); } }
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <aop:aspectj-autoproxy /> <bean id="audience" class="chapter4.Audience" /> <bean id="artist" class="chapter4.Artist" /> </beans>
(4)使用aop配置文件的自动代理
采用这种方法,不用加<aop:aspectj-autoproxy />
package chapter4; import org.aspectj.lang.annotation.Aspect; @Aspect public class Audience { public Audience() { } public void pointcut() { } public void takeSeats() { System.out.println("The audience is taking their seats."); } public void turnOffCellPhones() { System.out.println("The audience is turning off " + "their cellphones"); } public void applaud() { System.out.println("CLAP CLAP CLAP CLAP CLAP"); } public void demandRefund() { System.out.println("Boo! We want our money back!"); } }
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="audience" class="chapter4.Audience" /> <aop:config> <aop:aspect ref="audience"> <aop:before method="takeSeats" pointcut="execution(* *.perform(..))" /> <aop:before method="turnOffCellPhones" pointcut="execution(* *.perform(..))" /> <aop:after-returning method="applaud" pointcut="execution(* *.perform(..))" /> <aop:after-throwing method="demandRefund" pointcut="execution(* *.perform(..))" /> </aop:aspect> </aop:config> <bean id="artist" class="chapter4.Artist" /> </beans>