内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

Spring中AOP創(chuàng)建代理的方法

這篇文章主要講解了“Spring中AOP創(chuàng)建代理的方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Spring中AOP創(chuàng)建代理的方法”吧!

為江陵等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及江陵網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站建設(shè)、網(wǎng)站制作、江陵網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

1、準(zhǔn)備創(chuàng)建代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   //1.尋找增強(qiáng)器
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      //2.創(chuàng)建代理
      Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      return proxy;
   }
}
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
   //第六篇AOP尋找增強(qiáng)器已經(jīng)分析了該步驟
   List advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, 
                                                                                         TargetSource targetSource) {
   //對(duì)于代理類的創(chuàng)建及處理,交給了ProxyFactory去處理,此函數(shù)中只是做一些準(zhǔn)備工作
   ProxyFactory proxyFactory = new ProxyFactory();
   //獲取當(dāng)前類中相關(guān)屬性
   proxyFactory.copyFrom(this);

   if (!shouldProxyTargetClass(beanClass, beanName)) {
      //形如interface com.lwh.spring.JdkProxy.PersonService
      Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
      for (Class<?> targetInterface : targetInterfaces) {
         //添加代理接口
         proxyFactory.addInterface(targetInterface);
      }
   }
   
   //將攔截器封裝為增強(qiáng)器,此處的攔截器類型就是增強(qiáng)器
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   for (Advisor advisor : advisors) {
      //并添加到ProxyFactory中
      proxyFactory.addAdvisor(advisor);
   }
   //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@1130520d]
   proxyFactory.setTargetSource(targetSource);
   //定制代理,空實(shí)現(xiàn),由子類實(shí)現(xiàn)
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   //創(chuàng)建代理
   return proxyFactory.getProxy(this.proxyClassLoader);
}
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
   
   Advisor[] commonInterceptors = resolveInterceptorNames();

   List<Object> allInterceptors = new ArrayList<Object>();
   if (specificInterceptors != null) {
      //加入攔截器
      allInterceptors.addAll(Arrays.asList(specificInterceptors));
      if (commonInterceptors != null) {
         if (this.applyCommonInterceptorsFirst) {
            allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
         }
         else {
            allInterceptors.addAll(Arrays.asList(commonInterceptors));
         }
      }
   }

   Advisor[] advisors = new Advisor[allInterceptors.size()];
   for (int i = 0; i < allInterceptors.size(); i++) {
      //將攔截器轉(zhuǎn)化為Advisor
      advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
   }
   return advisors;
}
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
   if (adviceObject instanceof Advisor) {
      return (Advisor) adviceObject;
   }
   if (!(adviceObject instanceof Advice)) {
      throw new UnknownAdviceTypeException(adviceObject);
   }
   Advice advice = (Advice) adviceObject;
   if (advice instanceof MethodInterceptor) {
      return new DefaultPointcutAdvisor(advice);
   }
   for (AdvisorAdapter adapter : this.adapters) {
      if (adapter.supportsAdvice(advice)) {
         return new DefaultPointcutAdvisor(advice);
      }
   }
   throw new UnknownAdviceTypeException(advice);
}

2、創(chuàng)建代理

return proxyFactory.getProxy(this.proxyClassLoader);

public Object getProxy(ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}
//此函數(shù)真正完成了代理的創(chuàng)建
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   //三個(gè)條件影響Spring的判斷
   //1.optimize屬性,不推薦用戶使用這個(gè)設(shè)置
   //2.proxytargetclass屬性,之前分析過(guò)
   //3.是否存在代理接口
   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()) {
         //使用JDK動(dòng)態(tài)代理
         return new JdkDynamicAopProxy(config);
      }
      return CglibProxyFactory.createCglibProxy(config);
   }
   else {
      //目標(biāo)對(duì)象實(shí)現(xiàn)了接口,默認(rèn)使用JDK動(dòng)態(tài)代理
      return new JdkDynamicAopProxy(config);
   }
}

3、獲取代理

Spring中AOP創(chuàng)建代理的方法

public Object getProxy(ClassLoader classLoader) {
   //先是創(chuàng)建代理,再是獲取代理
   return createAopProxy().getProxy(classLoader);
}

public Object getProxy(ClassLoader classLoader) {
   //獲取代理接口,此處其實(shí)就是JDK的動(dòng)態(tài)代理實(shí)現(xiàn)了,建議復(fù)習(xí)下JDK的動(dòng)態(tài)代理
   Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   //返回代理對(duì)象
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
JDK動(dòng)態(tài)代理的關(guān)鍵就是實(shí)現(xiàn)InvocationHandler方法并實(shí)現(xiàn)其invoke方法,而此處的JdkDynamicAopProxy
實(shí)現(xiàn)了InvocationHandler接口,所以其中一定有invoke方法. 看筆記<JDK動(dòng)態(tài)代理>得知,獲取到的是代理對(duì)象
PersonService personService = ctx.getBean("personService", PersonService.class);
此處實(shí)際調(diào)用的是生成的代理類中的sayHello方法,看下圖,因?yàn)槭侵白龅墓P記,所以包名不一致,但意思很明顯,在代理類中sayHello方法
又會(huì)調(diào)用InvocationHandler中的invoke方法,此h對(duì)象,即InvocationHandler是在Proxy.newProxyInstance時(shí)設(shè)置進(jìn)去的,所以下面調(diào)用
sayHello方法時(shí)先會(huì)進(jìn)入JdkDynamicAopProxy的invoke方法personService.sayHello();

Spring中AOP創(chuàng)建代理的方法 Spring中AOP創(chuàng)建代理的方法

4、分析方法調(diào)用

//獲取代理對(duì)象
PersonService personService = ctx.getBean("personService", PersonService.class);
//方法調(diào)用
personService.sayHello();

Spring中AOP創(chuàng)建代理的方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   MethodInvocation invocation;
   Object oldProxy = null;
   boolean setProxyContext = false;
   //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852]
   TargetSource targetSource = this.advised.targetSource;
   Class targetClass = null;
   Object target = null;

   try {
      //刪去了部分代碼
      Object retVal;
      //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852]
      target = targetSource.getTarget();
      if (target != null) {
         //class com.lwh.spring.JdkProxy.PersonServiceImpl
         targetClass = target.getClass();
      }

      //獲取當(dāng)前方法的攔截器鏈
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      if (chain.isEmpty()) {
         //如果鏈為空,直接調(diào)用切點(diǎn)方法
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
      }
      else {
         //將攔截器封裝在ReflectiveMethodInvocation中,以便于使用其proceed方法進(jìn)行鏈接調(diào)用
         invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         //執(zhí)行攔截器鏈調(diào)用
         retVal = invocation.proceed();
      }

      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         retVal = proxy;
      } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
      }
      return retVal;
   }
   finally {
   }
}

Spring中AOP創(chuàng)建代理的方法

public Object proceed() throws Throwable {
   // We start with an index of -1 and increment early.
   //執(zhí)行完所有增強(qiáng)方法后執(zhí)行切點(diǎn)方法,維護(hù)了一個(gè)currentInterceptorIndex計(jì)數(shù)器,遞增
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }
   //List interceptorsAndDynamicMethodMatchers,記錄了要執(zhí)行的增強(qiáng)方法,通過(guò)下標(biāo)獲取要執(zhí)行的增強(qiáng)方法
   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);
   }
}

感謝各位的閱讀,以上就是“Spring中AOP創(chuàng)建代理的方法”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Spring中AOP創(chuàng)建代理的方法這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

分享文章:Spring中AOP創(chuàng)建代理的方法
當(dāng)前鏈接:http://www.rwnh.cn/article42/psgiec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、建站公司Google、小程序開發(fā)動(dòng)態(tài)網(wǎng)站、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
荔波县| 元朗区| 临潭县| 昔阳县| 普宁市| 阿勒泰市| 新田县| 正定县| 航空| 浦城县| 曲阜市| 长宁县| 攀枝花市| 应城市| 报价| 宣城市| 武陟县| 浦东新区| 永康市| 沈丘县| 土默特右旗| 大理市| 定西市| 徐水县| 北碚区| 勐海县| 饶河县| 教育| 晋城| 庆元县| 右玉县| 西充县| 福鼎市| 中超| 澳门| 宣恩县| 炉霍县| 灵台县| 东宁县| 兴宁市| 本溪|