AOP的XML配置:配置了两个BeanNameAutoProxyCreator,会怎么样?
在配置Spring AOP时,可以使用 org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator
来完成目标服务的拦截。 <bean id="serviceInteceptorProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>helloServiceAOP</value>
</list>
</property>
<property name="beanNames">
<value>
helloService
</value>
</property>
</bean>
<bean id="helloServiceAOP" class="com.bing.aoptest.aop.HelloServiceAOP" />
<bean id="helloService" class="com.bing.aoptest.service.HelloServiceImpl"></bean>
会在helloService的方法执行之前,先执行helloServiceAOP。 package com.bing.aoptest.service;
public class HelloServiceImpl implements HelloService {
public void say() {
System.out.println("Hello");
}
}
HelloServiceAOP定义如下: package com.bing.aoptest.aop;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class HelloServiceAOP implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("nHelloServiceAOP: "
+ invocation.getMethod().getDeclaringClass().getName());
return invocation.proceed();//放行,调用目标方法
}
}
那么,如果定义了两个BeanNameAutoProxyCreator会怎么样呢? <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="helloService" class="com.bing.aoptest.service.HelloServiceImpl"></bean>
<bean id="serviceInteceptorProxyCreator2" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>helloServiceInterceptor</value>
</list>
</property>
<property name="beanNames">
<value>
helloService
</value>
</property>
</bean>
<bean id="serviceInteceptorProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>helloServiceAOP</value>
</list>
</property>
<property name="beanNames">
<value>
helloService
</value>
</property>
</bean>
<bean id="helloServiceAOP" class="com.bing.aoptest.aop.HelloServiceAOP" />
<bean id="helloServiceInterceptor" class="com.bing.aoptest.aop.HelloServiceInterceptor" />
</beans>
helloServiceAOP和helloServiceInterceptor都拦截目标对象,但定义在不同的BeanNameAutoProxyCreator里面。 helloServiceAOP定义如下: package com.bing.aoptest.aop; import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInterceptor; public class HelloServiceAOP implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("nHelloServiceAOP: " + invocation.getMethod().getDeclaringClass().getName()); Method m = AOPUtil.getMethod(invocation); System.out.println("HelloServiceAOP,method对象:" + m); System.out.println("HelloServiceAOP,invocation对象:" + invocation); return invocation.proceed(); } } helloServiceInterceptor定义如下: package com.bing.aoptest.aop;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class HelloServiceInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("nHelloServiceInterceptor: "
+ invocation.getMethod().getDeclaringClass().getName());
Method m = AOPUtil.getMethod(invocation);
System.out.println("HelloServiceInterceptor,method对象:" + m);
System.out.println("HelloServiceInterceptor,invocation对象:"
+ invocation);
return invocation.proceed();
}
}
调用方法: package com.bing.aoptest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.bing.aoptest.service.HelloService;
/** * Hello world! * */
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
HelloService hs = (HelloService) context.getBean("helloService");
hs.say();
}
}
输出结果: HelloServiceAOP: com.bing.aoptest.service.HelloService
HelloServiceAOP,method对象:public final void com.sun.proxy.$Proxy0.say()
HelloServiceAOP,invocation对象:ReflectiveMethodInvocation: public abstract void com.bing.aoptest.service.HelloService.say(); target is of class [com.sun.proxy.$Proxy0]
HelloServiceInterceptor: com.bing.aoptest.service.HelloService
HelloServiceInterceptor,method对象:public void com.bing.aoptest.service.HelloServiceImpl.say()
HelloServiceInterceptor,invocation对象:ReflectiveMethodInvocation: public abstract void com.bing.aoptest.service.HelloService.say(); target is of class [com.bing.aoptest.service.HelloServiceImpl]
Hello
请注意: 为什么method对象不都是public void com.bing.aoptest.service.HelloServiceImpl.say()呢? 原因 所以,调用T的方法时,应该先执行P1,但P2代理了P1,最终先执行P2,再执行P1,在执行T。 这种情况下,如果T的方法上有注解,只有P1能够拿到注解信息,P2是拿不到的。 所以,不要定义个多个org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator的bean。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |