Spring源码学习之认识AOP
来源:互联网 发布:京东抢券软件安卓 编辑:程序博客网 时间:2024/06/06 01:08
前言
作为Spring的重要特性之一,AOP的作用当然是毋庸置疑的。它使我们可以在代码执行过程中,横切代码,封装那些重复执行的操作。保证代码的模块化和管理时的便捷性。而这篇博文将从源码的角度解析AOP的工作原理和使用过程:
简单的AOP实现
<!-- bean.xml --><bean id="testadvice" class="chapter3_AOP.TestAdvice"></bean><bean id="aop" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 可有可无 --> <property name="proxyInterfaces"> <value>chapter3_AOP.OperateApi</value> </property> <property name="target"> <bean class="chapter3_AOP.OperateTarget"></bean> </property> <property name="interceptorNames"> <list> <value>testadvice</value> </list> </property> </bean>
// OperateTarget.java public class OperateTarget implements OperateApi{ @Override public void update() { System.out.println("update"); }}
// TestAdvice.javapublic class TestAdvice implements MethodBeforeAdvice{ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("prehandle"); }}
// client.javapublic class client { public static void main(String []args){ ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); OperateApi api = (OperateApi)ac.getBean("aop"); api.update(); }}
// 输出prehandleupdate
AOP流程
1.生成代理对象
ProxyFactoryBean的实现是Spring IoC环境中创建AOP的底层方法,也是最灵活的方法。因此通过ProxyFactoryBean的使用,来看看AOP的运行到底是怎样的过程。
// ProxyFactoryBean.java// 获得生成的代理对象public Object getObject() throws BeansException { initializeAdvisorChain(); 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(); } }// 创建拦截器链private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException { // 如果已经初始化过了,那么直接返回 if (this.advisorChainInitialized) { return; } 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"); } // 遍历设置的拦截器 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"); } // 添加所有全局拦截器,主要过程是在beanfactory找出所有advisor和interceptor, // 添加到advisors中 addGlobalAdvisor((ListableBeanFactory) this.beanFactory, name.substring(0, name.length() - GLOBAL_SUFFIX.length())); } else { Object advice; if (this.singleton || this.beanFactory.isSingleton(name)) { // 之前分析过的从beanfactory中直接获取对象 advice = this.beanFactory.getBean(name); } else { advice = new PrototypePlaceholderAdvisor(name); } addAdvisorOnChainCreation(advice, name); } } } this.advisorChainInitialized = true; }// 添加拦截器private void addAdvisorOnChainCreation(Object next, String name) { // 将获得的类转换成advisor。如果是advice,将advice作为参数生成一个新的advisor Advisor advisor = namedBeanToAdvisor(next); if (logger.isTraceEnabled()) { logger.trace("Adding advisor with name '" + name + "'"); } addAdvisor(advisor); }// 获取单例实例private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { // 根据设置的targetName获取实例并包裹在targetSource中 this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // 获得Class 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); // 生成代理实例的关键 this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }private synchronized Object newPrototypeInstance() { // In the case of a prototype, we need to give the proxy // an independent instance of the configuration. // In this case, no proxy will have an instance of this object's configuration, // but will have an independent copy. if (logger.isTraceEnabled()) { logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this); } ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory()); // The copy needs a fresh advisor chain, and a fresh TargetSource. TargetSource targetSource = freshTargetSource(); copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain()); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. copy.setInterfaces( ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader)); } copy.setFrozen(this.freezeProxy); if (logger.isTraceEnabled()) { logger.trace("Using ProxyCreatorSupport copy: " + copy); } return getProxy(copy.createAopProxy()); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); } // DefaultAopProxyFactory.java @Override 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."); } // 如果是接口类或是是代理类,使用jdk动态代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }// 根据aopPorxy是哪种代理方式决定不同的生成object方式protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); }
//AdvisorSupport.java //以下代码主要功能在于将获取的advisor添加到advisors链表中,辅以清除缓存 @Override public void addAdvisor(Advisor advisor) { int pos = this.advisors.size(); addAdvisor(pos, advisor); } @Override public void addAdvisor(int pos, Advisor advisor) throws AopConfigException { if (advisor instanceof IntroductionAdvisor) { validateIntroductionAdvisor((IntroductionAdvisor) advisor); } addAdvisorInternal(pos, advisor); } private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException { Assert.notNull(advisor, "Advisor must not be null"); if (isFrozen()) { throw new AopConfigException("Cannot add advisor: Configuration is frozen."); } if (pos > this.advisors.size()) { throw new IllegalArgumentException( "Illegal position " + pos + " in advisor list with size " + this.advisors.size()); } this.advisors.add(pos, advisor); updateAdvisorArray(); adviceChanged(); } /** * Bring the array up to date with the list. */ protected final void updateAdvisorArray() { this.advisorArray = this.advisors.toArray(new Advisor[this.advisors.size()]); } protected void adviceChanged() { this.methodCache.clear(); }
下面就是jdk动态代理和cglib动态代理两种代理方式生成代理对象的过程:
jdk动态代理
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); // 根据类装载器和接口通过反射生成代理类 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
cglib动态代理
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, classLoader); // 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 ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); 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 above enhancer.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() failed throw new AopConfigException("Unexpected AOP exception", ex); }}
以上是实现生成代理对象的过程,而拦截器的步骤在于两种代理的回调。那么接下来就深入分析执行回调代码达到拦截器的作用。
2. 生成拦截链
以jdk动态代理回调为例,来看怎么为目标对象生成拦截链
// jdk动态代理的回调方法@Override 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)) { // 如果目标类没有实现equal,这里实现。 return equals(args[0]); } if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // 如果没有实现hashCode() return hashCode(); } if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // 通过反射调用方法并执行 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(); } // 这里获取对象所有的拦截链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 如果没有拦截链,或者说没有对应的增强 if (chain.isEmpty()) { // 直接使用反射执行对象方法 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // 否则新建ReflectiveMethodInvocation,依次执行拦截链的方法 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); } } }
// AdvisedSupport.java// 如果缓存中没有那么去生成拦截链public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }
// DefaultAdvisorChainFactory.javapublic List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, Class<?> targetClass) { // This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); for (Advisor advisor : config.getAdvisors()) { if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { // 根据advisor获取拦截链 MethodInterceptor[] interceptors = registry.getInterceptors(advisor); // 根据advisor切点获取匹配方法,即筛选可用的拦截链方法 MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { // Creating a new object instance in the getInterceptors() method // isn't a problem as we normally cache created chains. for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }
// DefaultAdvisorAdapterRegistry.java// 根据adviceadapter找到对应的interceptorpublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3); Advice advice = advisor.getAdvice(); if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if (interceptors.isEmpty()) { throw new UnknownAdviceTypeException(advisor.getAdvice()); } return interceptors.toArray(new MethodInterceptor[interceptors.size()]); }
// MethodBeforeAdviceAdapter@Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } // 根据advice获取对应的interceptor @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); }
3.实现advice中的增强
关键在与通过以下操作,实现增强功能的实现
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed();
// ReflectiveMethodInvocation.javaprotected ReflectiveMethodInvocation( Object proxy, Object target, Method method, Object[] arguments, Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) { this.proxy = proxy; this.target = target; this.targetClass = targetClass; this.method = BridgeMethodResolver.findBridgedMethod(method); this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; }public Object proceed() throws Throwable { // 从index为-1开始执行。如果执行到拦截链最末端,则通过反射执行对象方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // 依次获取拦截链中的拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 动态匹配方法再次匹配 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { // 如果匹配则调用拦截器的invoke方法 return dm.interceptor.invoke(this); } else { // 匹配不了,继续向下递归执行 return proceed(); } } else { return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
// 以methodBeforeAdvice为例看增强的调用public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; /** * Create a new MethodBeforeAdviceInterceptor for the given advice. * @param advice the MethodBeforeAdvice to wrap */ public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } // 回调invoke方法,调用advice中实现的增强before方法,再调用proceed,保证拦截链的向下执行 @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); }}
// AfterReturningAdvice也同样,唯一不同的是先执行拦截链方法,再执行本身advice的回调增强方法// 从而实现运行在目标增强方法后的情况public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { private final AfterReturningAdvice advice; /** * Create a new AfterReturningAdviceInterceptor for the given advice. * @param advice the AfterReturningAdvice to wrap */ public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }}
至此,完成advice的增强功能,整个aop实现完成。
小结
通过以上源码分析,已经从头到尾的梳理过AOP实现的整个功能:
- 获取配置信息生成advisor链。
- 根据不同情况区分使用jdk动态代理或者cglib动态代理。
- 根据advisor链中的切点和增强(advice)生成拦截链。
- 递归运行拦截链,判断动态匹配规则是否匹配。并根据增强不同串联上增强回调方法。
此时返回的aop代理对象,调用方法时,就回按照增强顺序依次调用增强方法和初始对象方法,实现了AOP增强的功能。
阅读全文
0 0
- Spring源码学习之认识AOP
- Spring源码学习之AOP
- spring源码学习之路---AOP初探
- Spring源码之AOP
- Spring Aop源码学习--Aop代理AopProxy
- Spring学习之AOP
- Spring学习之AOP
- 【Spring学习】之 AOP
- Spring学习之AOP
- Spring学习之AOP
- spring之AOP学习
- Spring学习之AOP
- 关于Spring之AOP的一些认识
- spring源码学习之路---AOP初探(六)
- spring源码学习之路---深入AOP(终)
- spring源码学习之路---AOP初探(六)
- spring源码学习之路---深入AOP(终)
- spring源码学习之路---深入AOP(终)
- UVa 1592 Database
- 通过串口log信息解决无限重启问题——空指针异常
- 2017开学训练第五周周中总结
- 解决CentOS下无法发送邮件的问题 + selinux
- 机器学习中的正则化
- Spring源码学习之认识AOP
- slf4j配置实例
- kafka可靠性
- jsp使用session对象模拟在线考试系统
- token android.os.BinderProxy@163442e0 is not valid; is your activity running
- InteliJ IDEA用Maven搭建Mybatis框架
- jQuery学习_动作效果(隐藏、显示、切换,滑动,淡入淡出,以及动画)
- POJ
- 据说这个说话的。。。。。。。那啥。