原文发表处:http://blog.youkuaiyun.com/zuoxiaolong8810/article/details/8917853
下面介绍下spring中的AOP核心接口。
Advice体系:
Spring采用AOP联盟的Advice作为超级接口,扩展了很多子接口,比如BeforeAdvice,AfterAdvice等等,稍后以AfterReturningAdvice为例,讨论下spring的通知体系。
Pointcut接口:
spring采用Pointcut作为切点的抽象,其中有一个方法返回一个MethodMatcher,作用很明显,就是说切点决定了要切入哪些方法。这里其实是定义了一个匹配规则。比如正则匹配,可以只匹配前缀为save的方法等等。
Advisor:
通知器或者说通知者,我们从现实角度来说,通知者当然需要知道要通知什么。所以Advisor依赖于Advice,而Advisor旗下的子接口PointAdvisor还依赖于Pointcut,也就是说这个接口更确切的定位应该是包含了要通知谁和要通知什么,也就是说要能获得Advice和Pointcut。
下面我们先用一个例子说明spring的AOP是如何工作的,在spring的bean中有一种特殊的bean,叫FactoryBean。这并不是一个普通的bean,而是用来产生bean的一个bean。这样说起来有点绕口,但这个接口就是用来做这个事的,它是为了实现一系列特殊加工过的bean而产生的接口。
比如AOP中,我们其实就是要对一个bean进行增强,进行加工,让它在运行的过程中可以做一些特殊的事情。
ProxyFactoryBean就是一个为了AOP实现的特殊的FactoryBean,它的作用很明显就是产生proxy的bean,也就是被我们增强过的bean,在这里给出它的源码。
下面是一个详细的例子,简单是解释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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="testAdvisor" class="com.springframework.aop.test.TestAdvisor"></bean> <bean id="testTarget" class="com.springframework.aop.test.TestTarget"></bean> <bean id="testAOP" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetName"> <value>testTarget</value> </property> <property name="interceptorNames"> <list> <value>testAdvisor</value> </list> </property> </bean> </beans>
public class TestTarget{
public void test() {
System.out.println("target.test()");
}
public void test2(){
System.out.println("target.test2()");
}
}
public class TestAdvisor implements PointcutAdvisor{
public Advice getAdvice() {
return new TestAfterAdvice();
}
public boolean isPerInstance() {
return false;
}
public Pointcut getPointcut() {
return new TestPointcut();
}
}
public class TestPointcut implements Pointcut{
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
public MethodMatcher getMethodMatcher() {
return new MethodMatcher() {
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
if (method.getName().equals("test")) {
return true;
}
return false;
}
public boolean matches(Method method, Class<?> targetClass) {
if (method.getName().equals("test")) {
return true;
}
return false;
}
public boolean isRuntime() {
return true;
}
};
}
}
public class TestAOP {
public static void main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:beans.xml");
TestTarget target = (TestTarget) applicationContext.getBean("testAOP");
target.test();
System.out.println("------无敌分割线-----");
target.test2();
}
}
运行结果如下:
target.test()
after TestTarget.test()
------无敌分割线-----
target.test2()