千家信息网

Spring中AOP创建代理的方法

发表于:2024-09-25 作者:千家信息网编辑
千家信息网最后更新 2024年09月25日,这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!1、准备创
千家信息网最后更新 2024年09月25日Spring中AOP创建代理的方法

这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!

1、准备创建代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {   //1.寻找增强器   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);   if (specificInterceptors != DO_NOT_PROXY) {      //2.创建代理      Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));      return proxy;   }}
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {   //第六篇AOP寻找增强器已经分析了该步骤   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) {   //对于代理类的创建及处理,交给了ProxyFactory去处理,此函数中只是做一些准备工作   ProxyFactory proxyFactory = new ProxyFactory();   //获取当前类中相关属性   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);      }   }      //将拦截器封装为增强器,此处的拦截器类型就是增强器   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);   //定制代理,空实现,由子类实现   customizeProxyFactory(proxyFactory);   proxyFactory.setFrozen(this.freezeProxy);   if (advisorsPreFiltered()) {      proxyFactory.setPreFiltered(true);   }   //创建代理   return proxyFactory.getProxy(this.proxyClassLoader);}
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {      Advisor[] commonInterceptors = resolveInterceptorNames();   List allInterceptors = new ArrayList();   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++) {      //将拦截器转化为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、创建代理

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);}
//此函数真正完成了代理的创建public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {   //三个条件影响Spring的判断   //1.optimize属性,不推荐用户使用这个设置   //2.proxytargetclass属性,之前分析过   //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动态代理         return new JdkDynamicAopProxy(config);      }      return CglibProxyFactory.createCglibProxy(config);   }   else {      //目标对象实现了接口,默认使用JDK动态代理      return new JdkDynamicAopProxy(config);   }}

3、获取代理

public Object getProxy(ClassLoader classLoader) {   //先是创建代理,再是获取代理   return createAopProxy().getProxy(classLoader);}public Object getProxy(ClassLoader classLoader) {   //获取代理接口,此处其实就是JDK的动态代理实现了,建议复习下JDK的动态代理   Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);   //返回代理对象   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
JDK动态代理的关键就是实现InvocationHandler方法并实现其invoke方法,而此处的JdkDynamicAopProxy实现了InvocationHandler接口,所以其中一定有invoke方法. 看笔记得知,获取到的是代理对象PersonService personService = ctx.getBean("personService", PersonService.class);此处实际调用的是生成的代理类中的sayHello方法,看下图,因为是之前做的笔记,所以包名不一致,但意思很明显,在代理类中sayHello方法又会调用InvocationHandler中的invoke方法,此h对象,即InvocationHandler是在Proxy.newProxyInstance时设置进去的,所以下面调用sayHello方法时先会进入JdkDynamicAopProxy的invoke方法personService.sayHello();

4、分析方法调用

//获取代理对象PersonService personService = ctx.getBean("personService", PersonService.class);//方法调用personService.sayHello();

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();      }      //获取当前方法的拦截器链      List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);      if (chain.isEmpty()) {         //如果链为空,直接调用切点方法         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);      }      else {         //将拦截器封装在ReflectiveMethodInvocation中,以便于使用其proceed方法进行链接调用         invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);         //执行拦截器链调用         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 {   }}

public Object proceed() throws Throwable {   // We start with an index of -1 and increment early.   //执行完所有增强方法后执行切点方法,维护了一个currentInterceptorIndex计数器,递增   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {      return invokeJoinpoint();   }   //List interceptorsAndDynamicMethodMatchers,记录了要执行的增强方法,通过下标获取要执行的增强方法   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创建代理的方法"的内容了,经过本文的学习后,相信大家对Spring中AOP创建代理的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0