AOP的XML配置:配置了两个BeanNameAutoProxyCreator,会怎么样?
来源:互联网 发布:苹果7支持的网络制式 编辑:程序博客网 时间:2024/06/02 11:07
在配置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。
HelloServiceImpl定义如下:
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配置如下:
<?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;
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()); 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.HelloServiceHelloServiceAOP, 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.HelloServiceHelloServiceInterceptor, 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
请注意:
HelloServiceAOP, method对象:public final void com.sun.proxy.$Proxy0.say()
HelloServiceInterceptor, method对象:public void com.bing.aoptest.service.HelloServiceImpl.say()
为什么method对象不都是public void com.bing.aoptest.service.HelloServiceImpl.say()呢?
原因
定义了两个org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator,按照顺序分别计作A,B,A会为目标对象T生成代理对象P1,B会为P1生成代理对象P2,代理逻辑就变成:
P2代理P1,P1代理T,而不是P2、P1都代理T。
所以,调用T的方法时,应该先执行P1,但P2代理了P1,最终先执行P2,再执行P1,在执行T。
这种情况下,如果T的方法上有注解,只有P1能够拿到注解信息,P2是拿不到的。
所以,不要定义个多个org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator的bean。
- AOP的XML配置:配置了两个BeanNameAutoProxyCreator,会怎么样?
- 配置BeanNameAutoProxyCreator
- Spring的ProxyFactoryBean和BeanNameAutoProxyCreator的配置
- Spring的ProxyFactoryBean和BeanNameAutoProxyCreator的配置
- BeanNameAutoProxyCreator配置例子
- BeanNameAutoProxyCreator配置例子
- aop的xml文件配置
- 配置了 Spring AOP 但会调用两次的问题解决方法
- Spring、XML配置AOP
- spring aop xml配置
- AOP XML方式配置
- Spring的AOP使用xml配置
- 基于XML的spring AOP配置
- Spring的AOP配置(基于xml)
- Spring的AOP编程XML配置
- Spring -- 基于XML的AOP通知配置
- 基于XML的Spring AOP配置
- 配置xml方式实现Spring的aop
- open和fopen的区别
- Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostn
- Tips
- C#实现http协议GET、POST请求
- C++之虚函数
- AOP的XML配置:配置了两个BeanNameAutoProxyCreator,会怎么样?
- android.view.WindowLeaked: Activity com.xty.activity.ActivityMainPage has leaked window com.android.
- Struts – Wildcards example
- Java多线程 -- 面试
- 中科院计算所培训中心2015年四季度公开课安排
- c语言字符串 数字转换函数大全
- Android ADB命令大全
- php 变量
- 挑战假设,尤其是你自己的