Spring
的经典
AOP
编程模型在现在看来已经过时,如果有人在写代码的时候还使用这种方式实现AOP,那真是跟自己过不去。但是如果我们想要读Spring AOP 部分的源码时,如果仅仅了解
声明式
AOP
和基于注解的
AOP,那经典的AOP模型所使用的类会给我们带来疑惑,所以,还是简单了解一下Spring AOP的历史,重温一下经典。
下面用一个小例子介绍一下经典AOP实现,在写代码的时候我希望记录整个写代码的过程,比如开始写代码的时间点,完成代码的时间点,以及写代码过程中遇到的BUG等信息。对于程序员来说,这些记录希望有一个程序能自动进行,不用自己去看时间记录,因为这属于写代码之外的事,我们拒绝执行。此时,这个记录功能就是一个横切关注点。
定义一个接口,有一个写代码接口
public interface ICoder {
public void writeCode();
}
Monkey类实现这个接口,作为被代理对象
public class Monkey implements ICoder {
@Override
public void writeCode() {
System.out.println("Writing Code!");
}
}
定义一个前置通知,记录写代码之前的时间点
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object instance) throws Throwable {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Before " + method.getName() + " " + df.format(new Date()));
}
}
定义一个后置通知,记录完成代码的时间点
public class AfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object value, Method method, Object[] args, Object instance) throws Throwable {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Finished " + method.getName() + " " + df.format(new Date()));
}
}
定义一个异常通知,在发现BUG时记录时间点
public class ExceptionAdvice implements ThrowsAdvice {
public void afterThrowing(Throwable t) throws Throwable {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Find a Bug " + t +" " + df.format(new Date()));
}
}
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="before" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="com.ink.spring.demo.aop.classic.BeforeAdvice"></bean>
</property>
<property name="patterns">
<list>
<value>.*Code.*</value>
</list>
</property>
</bean>
<bean id="after" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="com.ink.spring.demo.aop.classic.AfterAdvice"></bean>
</property>
<property name="patterns">
<list>
<value>.*Code.*</value>
</list>
</property>
</bean>
<bean id="exception" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="com.ink.spring.demo.aop.classic.ExceptionAdvice"></bean>
</property>
<property name="patterns">
<list>
<value>.*Code.*</value>
</list>
</property>
</bean>
<bean id="monkey" class="com.ink.spring.demo.aop.classic.Monkey" />
<!-- 代理 -->
<bean id="monkeyProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>before</value>
<value>after</value>
<value>exception</value>
</list>
</property>
<property name="target" ref="monkey" />
</bean>
</
beans
>
测试类
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ICoder coder = (ICoder) context.getBean("monkeyProxy");
coder.writeCode();
}
}
输出结果:
Before writeCode 2017-04-05 21:53:59
Writing Code!
Finished writeCode 2017-04-05 21:54:00