當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
spring aop实现过程之二Spring AOP中拦截器链
生活随笔
收集整理的這篇文章主要介紹了
spring aop实现过程之二Spring AOP中拦截器链
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.開始步驟--獲取AopProxy主流程
ProxyCreatorSupport.java
/*** Subclasses should call this to get a new AOP proxy. They should <b>not</b>* create an AOP proxy with <code>this</code> as an argument.*/protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}?
2.獲取AopProxy實現? --DefaultAopProxyFactory.java
ProxyFactoryBean類繼承了AdvisedSupport類,后者繼承了ProxyConfig類并定義了操作advisor 和interceptor的接口,以支持AOP。當BeanFactory實例化ProxyFactoryBean時,根據配置文件的定義將關于 advice,pointcut,advisor,所代理的接口和接口實現類的所有信息傳給ProxyFactoryBean。
當客戶程序調用BeanFactory的getBean方法時,ProxyFactory使用JdkDynamicAopProxy實例化 BeanImpl類,并用JdkDynamicAopProxy的invoke方法執行advice。至于執行advice的時機,由 ProxyFactoryBean調用RegexpMethodPointcutAdvisor進行判斷。 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);}if (!cglibAvailable) {throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. " +"Add CGLIB to the class path or specify proxy interfaces.");}return CglibProxyFactory.createCglibProxy(config);}else {return new JdkDynamicAopProxy(config);}}3.獲取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);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}4.激發攔截器鏈主過程
1 /** 2 * Implementation of <code>InvocationHandler.invoke</code>. 3 * <p>Callers will see exactly the exception thrown by the target, 4 * unless a hook method throws an exception. 5 */ 6 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 7 MethodInvocation invocation = null; 8 Object oldProxy = null; 9 boolean setProxyContext = false; 10 11 TargetSource targetSource = this.advised.targetSource; 12 Class targetClass = null; 13 Object target = null; 14 15 try { 16 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { 17 // The target does not implement the equals(Object) method itself. 18 return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE); 19 } 20 if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { 21 // The target does not implement the hashCode() method itself. 22 return new Integer(hashCode()); 23 } 24 if (!this.advised.opaque && method.getDeclaringClass().isInterface() && 25 method.getDeclaringClass().isAssignableFrom(Advised.class)) { 26 // Service invocations on ProxyConfig with the proxy config... 27 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); 28 } 29 30 Object retVal = null; 31 32 if (this.advised.exposeProxy) { 33 // Make invocation available if necessary. 34 oldProxy = AopContext.setCurrentProxy(proxy); 35 setProxyContext = true; 36 } 37 38 // May be <code>null</code>. Get as late as possible to minimize the time we "own" the target, 39 // in case it comes from a pool. 40 target = targetSource.getTarget(); 41 if (target != null) { 42 targetClass = target.getClass(); 43 } 44 45 // Get the interception chain for this method. 46 List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 47 48 // Check whether we have any advice. If we don't, we can fallback on direct 49 // reflective invocation of the target, and avoid creating a MethodInvocation. 50 if (chain.isEmpty()) { 51 // We can skip creating a MethodInvocation: just invoke the target directly 52 // Note that the final invoker must be an InvokerInterceptor so we know it does 53 // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. 54 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); 55 } 56 else { 57 // We need to create a method invocation... 58 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); 59 // Proceed to the joinpoint through the interceptor chain. 60 retVal = invocation.proceed(); 61 } 62 63 // Massage return value if necessary. 64 if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) && 65 !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { 66 // Special case: it returned "this" and the return type of the method 67 // is type-compatible. Note that we can't help if the target sets 68 // a reference to itself in another returned object. 69 retVal = proxy; 70 } 71 return retVal; 72 } 73 finally { 74 if (target != null && !targetSource.isStatic()) { 75 // Must have come from TargetSource. 76 targetSource.releaseTarget(target); 77 } 78 if (setProxyContext) { 79 // Restore old proxy. 80 AopContext.setCurrentProxy(oldProxy); 81 } 82 } 83 }5.獲取攔截器鏈DefaultAdvisorChainFactory.java
public List 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 interceptorList = new ArrayList(config.getAdvisors().length);boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();Advisor[] advisors = config.getAdvisors();for (int i = 0; i < advisors.length; i++) {Advisor advisor = advisors[i];if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor);MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {if (mm.isRuntime()) {// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.for (int j = 0; j < interceptors.length; j++) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptors[j], mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}else {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}6.激發攔截鏈工作實現 ---ReflectiveMethodInvocation.java
public Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}?
?
?
轉載于:https://www.cnblogs.com/davidwang456/archive/2013/03/19/2969417.html
總結
以上是生活随笔為你收集整理的spring aop实现过程之二Spring AOP中拦截器链的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring aop实现过程之一代理对象
- 下一篇: spring aop实现过程之三Spri