Spring技术内幕:Spring AOP的实现原理(三)
2017-08-03 12:18
155 查看
生成SingleTon代理对象在getSingleTonInstance方法中完毕,这种方法时ProxyFactoryBean生成AopProxy对象的入口。代理对象会封装对target目标对象的调用。也就是说针对target对象的方法调用行为会被这里生成的代理对象所拦截。
详细的生成过程是首先读取ProxyFactoryBean配置,为生成代理对象做好准备。Spring通过AopProxy类来详细生成代理对象。对于getSingleTonInstance方法中生成代理对象的步骤例如以下:
这里出现了AopProxy对象类型,Spring利用AOPProxy接口类把AOP代理对象的实现与框架其它部分有效隔离开来。
AopProxy接口有两个子类实现,一个Cglib2AopProxy,还有一个是JdkDynamicProxy。
详细代理对象的生成是在ProxyFactoryBean的基类AdvisedSupport中实现,借助AopProxyFactory完毕,这个对象要么从JDK中生成,要么借助CGLIB获得。
以下看看ProxyCreatorSupport中是怎样生成代理对象的。
AopProxy代理对象的生成有两种方式。假设目标对象是接口类使用JDK来生成,否则Spring会使用CGLIB来生成目标的代理对象。
以下看看在DefaultAopProxyFactory是怎样生成AopProxy目标代理对象的:
在AopProxy代理对象的生成过程中。首先要从AdviseSupport对象中取得配置的目标对象。AOP完毕的是切面应用对目标应用对象的增强。假设这里没有配置目标对象会直接抛出异常。一般而言,默认方式是使用JDK来产生AopProxy代理对象,但假设配置的目标对象不是接口类的实现,会使用CGLIB来产生AopProxy代理对象;在使用CGLIB来产生AopProxy代理对象时,由于CGLIB是第三方类库,本身不在JDK基类库中,全部须要在classPath中正确配置,以便可以载入和利用。在Spring中。使用JDK和CGLIB来生成AopProxy代理对象的工作,是由JdkDynamicAopProxy和CglibProxyFactory来完毕。
4、JDK生成AopProxy对象(接口实现类)
通过上面我们已经知道生成AopProxy对象有两种方式,以下看下类图:
我们先看下JdkDynamicAopProxy是怎样生成AopProxy对象的:
5、CGLIB生成AopProxy对象(非接口实现类)
四、Spring AOP拦截器调用的实现
1、设计原理
在Spring AOP通过JDK的Proxy方式或CGLIB方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了,拦截器在代理对象中起作用是通过对这些方法的回调来完毕的。
假设使用JDK的Proxy来生成代理对象,那么须要InvocationHandler来设置拦截器回调,而假设使用CGLIB来生成代理对象。通过DynamicAdvisedInterceptor来完毕回调。
2、JdkDynamicAopProxy的invoke拦截
在JDKDynamicAopProxy生成代理对象时,他的AopProxy代理对象生成调用:
this指的是InvocationHandler对象,InvocationHandler是JDK定义反射类的一个接口。这个接口定义了invoke方法,此方法为回调方法。
通过invoke的详细实现。来完毕对目标对象方法调用的拦截器或者功能增强工作。
在这种方法中。包括一个完整的拦截器链对目标对象的拦截过程。比方获取拦截器链中的拦截器进行配置。逐个执行拦截器链里的拦截器增强,知道最后的目标对象方法的执行。以下看下invoke的源代码
3、CglibAopProxy的intercept拦截器
使用CglibAopProxy生成AopProxy对象时候。对于AOP拦截器调用。回调的是DynamicAdvisedInterceptor对象生成的。
回调的方法时intercept,以下看看回调方法的源代码:
详细的生成过程是首先读取ProxyFactoryBean配置,为生成代理对象做好准备。Spring通过AopProxy类来详细生成代理对象。对于getSingleTonInstance方法中生成代理对象的步骤例如以下:
/** * Return the singleton instance of this class's proxy object, * lazily creating it if it hasn't been created already. * @return the shared singleton proxy */ private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. // 依据AOP框架来推断须要代理的接口 Class targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } // 这里设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); // 这里会使用ProxyFactoryBean来生成须要的proxy对象 this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }
/** * Return the proxy object to expose. * <p>The default implementation uses a {@code getProxy} call with * the factory's bean class loader. Can be overridden to specify a * custom class loader. * @param aopProxy the prepared AopProxy instance to get the proxy from * @return the proxy object to expose * @see AopProxy#getProxy(ClassLoader) */ protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); }
这里出现了AopProxy对象类型,Spring利用AOPProxy接口类把AOP代理对象的实现与框架其它部分有效隔离开来。
AopProxy接口有两个子类实现,一个Cglib2AopProxy,还有一个是JdkDynamicProxy。
详细代理对象的生成是在ProxyFactoryBean的基类AdvisedSupport中实现,借助AopProxyFactory完毕,这个对象要么从JDK中生成,要么借助CGLIB获得。
以下看看ProxyCreatorSupport中是怎样生成代理对象的。
/** * Subclasses should call this to get a new AOP proxy. They should <b>not</b> * create an AOP proxy with {@code this} as an argument. */ protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // 通过AopProxyFactory取得AopProxy,这个AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory return getAopProxyFactory().createAopProxy(this); }
AopProxy代理对象的生成有两种方式。假设目标对象是接口类使用JDK来生成,否则Spring会使用CGLIB来生成目标的代理对象。
以下看看在DefaultAopProxyFactory是怎样生成AopProxy目标代理对象的:
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 CglibProxyFactory.createCglibProxy(config); } else { return new JdkDynamicAopProxy(config); } }
在AopProxy代理对象的生成过程中。首先要从AdviseSupport对象中取得配置的目标对象。AOP完毕的是切面应用对目标应用对象的增强。假设这里没有配置目标对象会直接抛出异常。一般而言,默认方式是使用JDK来产生AopProxy代理对象,但假设配置的目标对象不是接口类的实现,会使用CGLIB来产生AopProxy代理对象;在使用CGLIB来产生AopProxy代理对象时,由于CGLIB是第三方类库,本身不在JDK基类库中,全部须要在classPath中正确配置,以便可以载入和利用。在Spring中。使用JDK和CGLIB来生成AopProxy代理对象的工作,是由JdkDynamicAopProxy和CglibProxyFactory来完毕。
4、JDK生成AopProxy对象(接口实现类)
通过上面我们已经知道生成AopProxy对象有两种方式,以下看下类图:
我们先看下JdkDynamicAopProxy是怎样生成AopProxy对象的:
public 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); // 调用JDK生成Proxy return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
5、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... // 来自advised的IOC配置。比方使用AOP的DynamicAdvisedInterceptor 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 MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class)); enhancer.setInterceptDuringConstruction(false); // 通过设置DynamicAdvisedInterceptor拦截器来完毕AOP功能,getCallBacks方法例如以下: // Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised) Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); enhancer.setCallbacks(callbacks); // Generate the proxy class and create a proxy instance. Object proxy; if (this.constructorArgs != null) { proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs); } else { proxy = enhancer.create(); } return proxy; } 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() failed throw new AopConfigException("Unexpected AOP exception", ex); } }
四、Spring AOP拦截器调用的实现
1、设计原理
在Spring AOP通过JDK的Proxy方式或CGLIB方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了,拦截器在代理对象中起作用是通过对这些方法的回调来完毕的。
假设使用JDK的Proxy来生成代理对象,那么须要InvocationHandler来设置拦截器回调,而假设使用CGLIB来生成代理对象。通过DynamicAdvisedInterceptor来完毕回调。
2、JdkDynamicAopProxy的invoke拦截
在JDKDynamicAopProxy生成代理对象时,他的AopProxy代理对象生成调用:
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
this指的是InvocationHandler对象,InvocationHandler是JDK定义反射类的一个接口。这个接口定义了invoke方法,此方法为回调方法。
通过invoke的详细实现。来完毕对目标对象方法调用的拦截器或者功能增强工作。
在这种方法中。包括一个完整的拦截器链对目标对象的拦截过程。比方获取拦截器链中的拦截器进行配置。逐个执行拦截器链里的拦截器增强,知道最后的目标对象方法的执行。以下看下invoke的源代码
/** * Implementation of {@code InvocationHandler.invoke}. * <p>Callers will see exactly the exception thrown by the target, * unless a hook method throws an exception. */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Class<?> targetClass = null; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be null. Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // Get the interception chain for this method. // 获得定义好的拦截器 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // Check whether we have any advice. If we don't, we can fallback on direct // reflective invocation of the target, and avoid creating a MethodInvocation. // 假设没有拦截器直接调用target的相应方法 if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly // Note that the final invoker must be an InvokerInterceptor so we know it does // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. // 假设有拦截器设定,那么须要调用拦截器之后才调用目标对象相应的方法 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); } // Massage return value if necessary. Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { // Special case: it returned "this" and the return type of the method // is type-compatible. Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
3、CglibAopProxy的intercept拦截器
使用CglibAopProxy生成AopProxy对象时候。对于AOP拦截器调用。回调的是DynamicAdvisedInterceptor对象生成的。
回调的方法时intercept,以下看看回调方法的源代码:
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Class<?> targetClass = null; Object target = null; try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be null. Get as late as possible to minimize the time we // "own" the target, in case it comes from a pool... target = getTarget(); if (target != null) { targetClass = target.getClass(); } List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. retVal = methodProxy.invoke(target, args); } else { // We need to create a method invocation... retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null) { releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
相关文章推荐
- Spring技术内幕:Spring AOP的实现原理(五)
- Spring技术内幕:Spring AOP的实现原理(三)
- Spring技术内幕:Spring AOP的实现原理(一)
- Spring技术内幕:Spring AOP的实现原理(二)
- Spring技术内幕:Spring AOP的实现原理(二)
- Spring技术内幕:Spring AOP的实现原理(一)
- Spring技术内幕:Spring AOP的实现原理(四)
- Spring技术内幕:Spring AOP的实现原理(五)
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- ppst——技术视频spring AOP 的原理讲解和简单实现
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- Spring技术内幕——深入解析Spring架构与设计原理 ----IOC实现原理
- Spring技术内幕——深入解析Spring架构与设计原理(四)Web MVC的实现
- Spring技术内幕3——Spring AOP原理(一)
- AOP技术应用和研究--SpringAop实现原理
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
- spring技术内幕之spring aop的实现