Spring AOP的实现之建立AopProxy代理对象
来源:互联网 发布:中国象棋电脑软件 编辑:程序博客网 时间:2024/05/17 21:52
在Spring的AOP模块中,一个主要的部分是代理对象的生成,而对于Spring应用,可以看到,是通过配置和调用ProxyFactoryBean来完成这个任务的。
在ProxyFactoryBean中,封装了主要代理对象的生成过程。在生成过程可以使用两种方法,一种是JDK的Proxy,另一种是CGLIB。
以ProxyFactory的设计为中心,可以看到相关的类继承关系。
ProxyConfig作为共同的基类,它为各种子类提供了配置属性。
AdvisorSupport的实现中,封装了AOP对通知和通知器的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但
对于具体的AOP代理对象的创建,AdvisorSupport把它交给它的子类去完成。
ProxyCreatorSupport,可以将它看成是其子类创建AOP代理对象的辅助类。
具体AOP代理对象的生成,根据不同的需要,分别由AspectProxyFactory、ProxyFactory、ProxyFactoryBean来完成。
对于需要使用AspectJ的AOP应用,AspectProxyFactory起到Spring和AspectJ的集成。
ProxyFactoryBean,可以在IoC容器中完成声明式的配置。
ProxyFactory需要编程地使用Spring AOP的功能。
下面详细介绍从配置ProxyFactoryBean开始到具体的代理对象生成。
基于XML配置Spring
<bean id="testAdvisor" class="com.abc.TestAdvisor"/> <bean id="testAOP" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.test.AbcInterface</value> </property> <property name="target"> <bean class="com.abc.TestTarget"/> </property> <property name="interceptorNames"> <list> <value>testAdvisor</value> </list> </property> </bean>(1)定义使用的通知器Advisor,这个通知器应该作为一个Bean来定义。这个通知器的实现定义了需要对目标对象进行增强的切面
行为,也就是Advice通知。
(2)定义ProxyFactoryBean,把它作为另一个bean来定义,它是封装AOP功能的主要类。在配置ProxyFactoryBean需要配置与其相关的属性:
interceptorNames属性的值往往设置为需要定义的通知器。这些通知器在ProxyFactoryBean配置下,是通过使用代理对象的拦截器机制起作用的。
作为target属性注入的bean,是需要用AOP通知器中的切面应用来增强的对象。
ProxyFactoryBean生成AopProxy代理对象
ProxyFactoryBean的AOP实现需要依赖JDK或者CGLIB提供的Proxy特性。从FactoryBean中获取对象,是以getObject方法作为入口完成的;
ProxyFactoryBean实现中的getObject方法,是FactoryBean需要实现的接口。对ProxyFactoryBean来说,把需要对target目标对象增加的增强处理,都通过
getObject方法进行封装了,这些增强处理是为AOP功能的实现提供服务的。
ProxyFactoryBean类中的getObject方法
@Overridepublic Object getObject() throws BeansException {initializeAdvisorChain();//初始化通知器链,为Proxy代理对象配置Advisor链是在这个方法中完成的 //这里对singleton和prototyope的类型进行区分,生成对应的proxy if (isSingleton()) {return getSingletonInstance();}else {if (this.targetName == null) {logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +"Enable prototype proxies by setting the 'targetName' property.");}return newPrototypeInstance();}}ProxyFactoryBean中的initialzeAdvisorChain方法
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {if (this.advisorChainInitialized) {//这是一个标志位,用来表示通知器链是否已经初始化。如果初始化,这里就不再初始化,而是直接返回。return; //也就是说初始化的工作发生在应用第一次通过ProxyFactoryBean去获取代理对象的时候。}if (!ObjectUtils.isEmpty(this.interceptorNames)) {if (this.beanFactory == null) {throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));}if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) { throw new AopConfigException("Target required after globals"); } //这里是添加Advisor链的调用,是通过interceptorNames属性进行配置的 for (String name : this.interceptorNames) { if (logger.isTraceEnabled()) {logger.trace("Configuring advisor or advice '" + name + "'");} if (name.endsWith(GLOBAL_SUFFIX)) { if (!(this.beanFactory instanceof ListableBeanFactory)) { throw new AopConfigException( "Can only use global advisors or interceptors with a ListableBeanFactory"); } addGlobalAdvisor((ListableBeanFactory) this.beanFactory, name.substring(0, name.length() - GLOBAL_SUFFIX.length())); }else {// 如果程序在这里被调用,那么需要加入命名的拦截器advice,并且需要检查这个Bean// 是singleton还是prototype类型 Object advice; if (this.singleton || this.beanFactory.isSingleton(name)) { // 添加advice或者advisoradvice = this.beanFactory.getBean(name); }else {// 对prototype类型Bean的处理advice = new PrototypePlaceholderAdvisor(name);}addAdvisorOnChainCreation(advice, name);}} }this.advisorChainInitialized = true;}生成singleton的代理对象是在getSingletonInstance()完成的,这个方法是ProxyFactoryBean生成AopProxy代理对象的调用入口。
代理对象会封装对target目标对象的调用,也就是说针对target对象的方法调用会被这里生成的代理对象所拦截。getSingletonInstance方法的具体实现为:
private synchronized Object getSingletonInstance() {if (this.singletonInstance == null) {this.targetSource = freshTargetSource();//首先读取ProxyFactoryBean中的配置if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { //根据AOP框架来判断需要代理的接口Class<?> targetClass = getTargetClass();if (targetClass == null) {throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");} //这里设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));}super.setFrozen(this.freezeProxy); this.singletonInstance = getProxy(createAopProxy());//使用ProxyFactory来生成需要的Proxy}return this.singletonInstance;} protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); }具体代理对象的生成,是在ProxyCreatorSupport的基类AdvisedSupport的实现中借助AopProxyFactory完成的。因为ProxyFactoryBean本身就是AdvisedSupport的
子类,所以在ProxyFactoryBean中取得AopProxy是很方便的,而具体的AopProxy是通过AopProxyFactory来生成的。
createProxy()方法是ProxyCreatorSupport类中实现的:
protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();} //通过AopProxyFactory来创建AopProxy,AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory return getAopProxyFactory().createAopProxy(this);}所以在DefaultAopProxyFactory中有createAopProxy方法
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}if (targetClass.isInterface()) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);}else {return new JdkDynamicAopProxy(config);}}在这个方法中将会进行对targetClass进行判断,如果是接口类,便使用JDK来生成Proxy;如果不是接口类,那么使用CGLIB来生成。
在AopProxy代理对象的生成过程中,首先要从AdvisedSupport对象中取得配置的目标对象,这个目标对象是实现AOP功能所必需的。
AopProxy代理对象可以由JDK或CGLIB来生成,而JdkDynamicAopProxy和CglibAopProxy的实现都是通过AopProxy接口。
JDK生成AopProxy代理对象
@Overridepublic Object getProxy(ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());}Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
CGLIB生成AopProxy代理对象
public Object getProxy(ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());}try {Class<?> rootClass = this.advised.getTargetClass();Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");Class<?> proxySuperClass = rootClass;if (ClassUtils.isCglibProxyClass(rootClass)) {proxySuperClass = rootClass.getSuperclass();Class<?>[] additionalInterfaces = rootClass.getInterfaces();for (Class<?> additionalInterface : additionalInterfaces) {this.advised.addInterface(additionalInterface);}}// Validate the class, writing log messages as necessary.validateClassIfNecessary(proxySuperClass);// Configure CGLIB Enhancer...Enhancer enhancer = createEnhancer();if (classLoader != null) {enhancer.setClassLoader(classLoader);if (classLoader instanceof SmartClassLoader &&((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {enhancer.setUseCache(false);}}enhancer.setSuperclass(proxySuperClass);enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));Callback[] callbacks = getCallbacks(rootClass);Class<?>[] types = new Class<?>[callbacks.length];for (int x = 0; x < types.length; x++) {types[x] = callbacks[x].getClass();}// fixedInterceptorMap only populated at this point, after getCallbacks call aboveenhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));enhancer.setCallbackTypes(types);// Generate the proxy class and create a proxy instance.return createProxyClassAndInstance(enhancer, callbacks);}catch (CodeGenerationException ex) {throw new AopConfigException("Could not generate CGLIB subclass of class [" +this.advised.getTargetClass() + "]: " +"Common causes of this problem include using a final class or a non-visible class",ex);}catch (IllegalArgumentException ex) {throw new AopConfigException("Could not generate CGLIB subclass of class [" +this.advised.getTargetClass() + "]: " +"Common causes of this problem include using a final class or a non-visible class",ex);}catch (Exception ex) {// TargetSource.getTarget() failedthrow new AopConfigException("Unexpected AOP exception", ex);}}
这样,通过使用AopProxy对象封装target目标对象之后,ProxyFactoryBean的getObject方法得到的对象就不是一个普通的java对象,而是一个AopProxy代理对象。
在ProxyFactoryBean中配置的target目标对象,已经不会让应用直接调用其方法实现,而是作为AOP实现的一部分。对target目标对象的方法调用会首先被AopProxy代理对象
拦截,对不同的AopProxy代理对象生成方式,会使用不同的拦截回调入口。
- Spring AOP的实现之建立AopProxy代理对象
- Spring Aop原理分析(一) - 建立AopProxy代理对象
- Spring源码分析----建立AopProxy代理对象和AOP拦截器的调用
- 【Spring源码--AOP的实现】(一)AopProxy代理对象的创建
- Spring Aop源码学习--Aop代理AopProxy
- Spring AOP框架学习笔记(1):AOP代理对象的建立
- spring aop实现过程之一代理对象的生成
- 代理实现spring的AOP
- Spring AOP的实现原理之代理创建
- ProxyFactoryBean生成AopProxy代理对象-3
- Spring AOP 代理对象的生成 part3
- Spring之AOP的实现(JDK动态代理:只能代理接口,不能代理类)
- spring aop 代理实现
- Spring的无接口代理实现AOP
- Spring AOP 的实现原理----动态代理
- Spring的AOP是如何实现代理
- Spring基于代理的AOP实现
- Spring AOP之基于ProxyFactoryBean的代理
- 哈哈
- HDU 4791 Alice's Print Service(二分)
- JavaMail使用之属性的构建
- 分布式文件系统介绍
- 世界向何处去,和平发展还有没有可能?中国如何抓住第二个重要的战略机遇期?
- Spring AOP的实现之建立AopProxy代理对象
- 数据仓库数据挖掘——数据仓库中的ETL和元数据
- 第九周项目六穷举法解决组合问题(2)换分币
- HTML5:footer定位(底部+居中)的探讨+div图片居中问题
- 对新手程序员的一些唠叨
- JavaScript学习笔记(十四) 立即执行函数
- Mark一下
- java NIO详解
- android——1