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
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(); } //获取当前方法的拦截器链 Listchain = 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创建代理的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!
分享标题:Spring中AOP创建代理的方法
文章起源:http://cdiso.cn/article/psgiec.html