1.创建经典的Spring切面
定义业务类
public interface Performer {
void perform();
}
public class Stevie implements Performer {
public void perform() {
System.out.println("Stevie showing");
}
}
定义一个观众类Audience
public class 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 demandRedund(){//要求退票(演出失败之后执行,出现异常)
System.out.println("Boo! We want our money back!");
}
}
创建通知(前通知,后通知以及抛出后通知)AudienceAdvice
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(Throwable throwable) {// 抛出异常之后执行
audience.demandRedund();
}
}
定义AspectJ切点以及使用ProxyFactoryBean配置XML
<bean id="stevieTarget" class="com.springinaction.chapter04.classicAOP.Stevie"/>
<bean id="audience" class="com.springinaction.chapter04.classicAOP.Audience"/>
<bean id="audienceAdvice" class="com.springinaction.chapter04.classicAOP.AudienceAdvice">
<property name="audience" ref="audience"/>
</bean>
<bean id="adienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="advice" ref="audienceAdvice"/>
<property name="expression" value="execution(* *.perform(..))"/>
</bean>
<bean id="audienceProxyBase" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true">
<property name="proxyInterfaces" value="com.springinaction.chapter04.Performer"/>
<property name="interceptorNames" value="adienceAdvisor"/>
</bean>
<bean id="stevie" parent="audienceProxyBase">
<property name="target" ref="stevieTarget"/>
</bean>
junit测试:
@Test
public void property(){
Performer performer = (Performer) act.getBean("stevie");
performer.perform();
}
控制台输出:
The audience is taking their seats.
The audience is turning off their cellphones
Stevie showing
CLAP CLAP CLAP CLAP CLAP
2.自动代理
根据上述程序代码,修改其配置XML实现自动代理:
<bean id="audience" class="com.springinaction.chapter04.classicAOP.Audience"/>
<bean id="audienceAdvice" class="com.springinaction.chapter04.classicAOP.AudienceAdvice">
<property name="audience" ref="audience"/>
</bean>
<bean id="adienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="advice" ref="audienceAdvice"/>
<property name="expression" value="execution(* *.perform(..))"/>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="stevie" class="com.springinaction.chapter04.classicAOP.Stevie"/>
3.定义纯粹的POJO切面
在XML文件中引入aop命名空间
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>
利用aop命名空间定义切面:
<bean id="audience" class="com.springinaction.chapter04.classicAOP.Audience"/>
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression="execution(* *.perform(..))"/>
<aop:before method="takeSeats" pointcut-ref="performance"/>
<aop:before method="turnOffCellPhones" pointcut-ref="performance"/>
<aop:after-returning method="applaud" pointcut-ref="performance"/>
<aop:after-throwing method="demandRedund" pointcut-ref="performance"/>
</aop:aspect>
</aop:config>
<bean id="stevie" class="com.springinaction.chapter04.classicAOP.Stevie"/>