Spring 版本 4.3.2java
在拿到 Bean 实例之后,会经历一系列的初始化工做,如:工厂回调、init 方法、后处理器在 Bean 初始化先后的处理等,在通常状况下(非 factory-method 建立的 Bean 等),AOP代理对象的建立就在后处理器的处理方法中实现。spring
以 AbstractAutowireCapableBeanFactory 类中的 initializeBean 方法做为起始点进行跟踪缓存
/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * * 初始化给定的 bean 实例,应用工厂回调方法以及 init 方法和 bean 的后处理器。 * 该方法会被传统定义 bean 的 createBean 方法所调用,也会被重载方法所引用 */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 后处理器的前调用 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 初始化后,进行后处理器的后调用,跟踪此方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
依然在 AbstractAutowireCapableBeanFactory 类中。app
拿到 BeanFactory 中全部针对 Bean 的后处理器集合,依次调用。ide
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { // 利用处理器的处理方法,对 bean 实例进行处理,并返回一个对象 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
在后处理器集合中,有一个处理器叫作 AnnotationAwareAspectJAutoProxyCreator 建立器,该处理器在解析<aop:config>
标签、或者解析相关注解时被注册到工厂中,以下:post
// 若是必要的话注册AspectJ自动代理建立器 public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { // 传递了 AspectJAwareAdvisorAutoProxyCreator 的 Class,进入这个方法 return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source); } private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //工厂中是否已经注册了 org.springframework.aop.config.internalAutoProxyCreator if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); //若是已经有注册了 internalAutoProxyCreator,而且和入参传递的Class不是同一个Class, //那么就根据优先级进行选择 if (!cls.getName().equals(apcDefinition.getBeanClassName())) { //类 AopConfigUtils 中有个 ArrayList 属性 APC_PRIORITY_LIST,在类静态构造中依次加入了 //几个建立器,这个方法就是查找某个建立器在 APC_PRIORITY_LIST 中的索引,若是没有找到就报错 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); // internalAutoProxyCreator 的索引为0,入参的 AspectJAwareAdvisorAutoProxyCreator // 索引为1,后者要大,因此从新设置下 apcDefinition 的 beanClass if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } //直接返回null return null; } // 若是没有注册 internalAutoProxyCreator ,组装一个 Bean Definition,以 // AspectJAwareAdvisorAutoProxyCreator 做为 bean Class,而后注册到工厂中 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
从上面能够看见建立器 AnnotationAwareAspectJAutoProxyCreator 的注册通过,Bean Definition 是对 Bean 的描述,建立 bean 对象时,会以 Bean Definition 为依据进行实例化和初始化。优化
查看建立器的处理方法postProcessAfterInitialization
ui
该方法在建立器的超类 AbstractAutoProxyCreator 中实现this
/** * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * * 若是 bean 被定义为子类代理,则使用已配置的拦截器建立代理 */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // 缓存中没有的状况 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } /** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * * 必要的话包装给定的 bean,即,他有资格被代理 */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } // advisedBeans 存放 bean 是否能够被代理的信息,做为缓存,避免重复判断 // Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<> if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 若是 bean 是一些特殊的类,好比 Pointcut/Advisor,又或者没有 @Aspect 注解等 // 这些 bean 不该该被代理,信息存放到 advisedBeans 集合中 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 若是有通知,建立代理 // 拿到全部匹配该 bean 的通知,若是使用了切入点表达式或者 AspectJ 风格的加强, // 还须要在通知链的开始处添加 ExposeInvocationInterceptor 拦截器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { // 通知链不为null,能够代理 this.advisedBeans.put(cacheKey, Boolean.TRUE); // 建立代理对象,进入跟踪 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 存放已经生成代理对象的类信息 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
该方法在 AbstractAutoProxyCreator 中实现lua
/** * Create an AOP proxy for the given bean. * * 为指定的 bean 建立一个 AOP 代理 */ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { // 在 beanFactory 中,beanName 有对应的 BeanDefinition,此方法就是为 BeanDefinition 的 // attributes 属性添加键值对,key 为 xxx.originalTargetClass , value 包含了 targetSource AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); // 将建立器中的一些属性拷贝到新建立的代理工厂 proxyFactory.copyFrom(this); // proxyTargetClass 属性对代理方式的肯定有很是大的影响 // 当从建立器中拷贝的属性 proxyFactory 为 false 时,下面的两个方法须要详细跟踪 if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 对拦截器或者通知进行包装,包装成Advisor对象 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); // 在代理工厂中添加 Advisor 通知链 proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); // 子类中若是没有覆盖,那么此方法为空实现 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 经过代理工厂获取代理 return proxyFactory.getProxy(getProxyClassLoader()); }
proxyTargetClass 布尔属性值的肯定对代理方式有着很是大的影响。
当配置了<aop:aspectj-autoproxy>
,使用注解方式时;又或者是使用xml配置<aop:config>
时,两个标签都具备的proxy-target-class
属性默认为 false
那么上述步骤建立 ProxyFactory 对象时,从建立器中拷贝的 proxyTargetClass 属性则为 false,进入条件
if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } }
先看第一个方法shouldProxyTargetClass
该方法在 AbstractAutoProxyCreator 中实现
/** * Determine whether the given bean should be proxied with its target class rather than its interfaces. * <p>Checks the {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute} * of the corresponding bean definition. * * 肯定给定的bean是否应该使用其目标类而不是其接口进行代理。 * 检查对应 bean definition 的 preserveTargetClass 属性。 */ protected boolean shouldProxyTargetClass(Class<?> beanClass, String beanName) { return (this.beanFactory instanceof ConfigurableListableBeanFactory && AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)); }
工厂默认实现 DefaultListableBeanFactory 类实现了 ConfigurableListableBeanFactory 接口。
跟踪 AutoProxyUtils 类的 shouldProxyTargetClass 方法。
public static boolean shouldProxyTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) { // 工厂中有对应 beanName 的 bean definition 则进入条件 if (beanName != null && beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = beanFactory.getBeanDefinition(beanName); // bean definition 的 attributes 属性中是否有 // org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass // 为 key 的属性,且 value 为 ture return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE)); } return false; }
若是被代理 bean 对应的 bean definition 属性中,存在org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
为 key,且 值为 true 的 attributes
那么设置 proxyTargetClass 为 ture
再看第二个方法
该方法在类 ProxyProcessorSupport 中实现,ProxyProcessorSupport 是 AbstractAutoProxyCreator 的父类
/** * Check the interfaces on the given bean class and apply them to the {@link ProxyFactory}, * if appropriate. * <p>Calls {@link #isConfigurationCallbackInterface} and {@link #isInternalLanguageInterface} * to filter for reasonable proxy interfaces, falling back to a target-class proxy otherwise. * * 检查指定 bean class 上的接口,若是合适的话设置到 ProxyFactory 中。 * 调用 isConfigurationCallbackInterface 方法和 isInternalLanguageInterface 方法去过滤获得 * 合理的代理接口,不然回退到 target-class proxy */ protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) { // 此方法拿到类上及其父类上,全部的接口,不会递归获取接口上的接口 Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader()); boolean hasReasonableProxyInterface = false; // 遍历全部的接口,并进行过滤 for (Class<?> ifc : targetInterfaces) { // 接口中不能有像 Aware、InitializingBean 等容器的回调接口 // 接口的 ClassName 也不能是以 .cglib.proxy.Factory 结尾或者是 groovy.lang.GroovyObject // 这样的内部语言接口 if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) { // 若是还有接口剩余,则存在合适的代理接口 hasReasonableProxyInterface = true; break; } } if (hasReasonableProxyInterface) { // 将代理接口一个个添加到 proxyFactory 中 for (Class<?> ifc : targetInterfaces) { proxyFactory.addInterface(ifc); } } else { // 否者 proxyTargetClass 属性设置为 true proxyFactory.setProxyTargetClass(true); } }
总结一下两个方法
当 xml 中没有配置 proxyTargetClass 属性,默认为 false
若是被代理 bean 对应的 bean definition ,它的 attributes 属性中,存在org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
为 key,值为 true 的键值对
那么设置 proxyTargetClass 为 ture
不然过滤全部接口,接口不能为 Aware、InitializingBean 等容器的回调接口,也不能是内部语言接口
若是没有合适的接口,proxyTargetClass 仍是设置为 true 。
接下来看下代理工厂获取代理的流程。
进入 ProxyFactory 类中,跟踪 getProxy 方法
/** * Create a new proxy according to the settings in this factory. * <p>Can be called repeatedly. Effect will vary if we've added * or removed interfaces. Can add and remove interceptors. * <p>Uses the given class loader (if necessary for proxy creation). * * 根据这个 factory 的设置建立一个新的代理。 * 能够被重复调用。若是咱们添加或者移除了接口,会有影响。 * 能够添加和移除拦截器。 * 使用指定的类加载器(若是须要代理建立) */ public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
先跟踪 createAopProxy 方法,此方法在 ProxyCreatorSupport 类中实现,ProxyFactory 是其子类。
/** * Subclasses should call this to get a new AOP proxy. They should <b>not</b> * create an AOP proxy with {@code this} as an argument. * * 子类应该调用这个方法去得到一个新的AOP代理。他们不该该用 this 做为参数建立一个AOP代理 */ protected final synchronized AopProxy createAopProxy() { // 当AOP代理第一次被建立时,active会被设置为true if (!this.active) { // 设置 active 为 true,激活代理配置 activate(); } return getAopProxyFactory().createAopProxy(this); }
getAopProxyFactory 方法拿到的是 DefaultAopProxyFactory 的实例,它的接口是 AopProxyFactory
ProxyFactory 类间接继承 AdvisedSupport ,AdvisedSupport 继承 ProxyConfig ,做为配置存在
ProxyFactory 类和 DefaultAopProxyFactory 并无继承关系
以 ProxyFactory 类的实例为参数,调用 createAopProxy 方法,继续跟踪
此方法在 DefaultAopProxyFactory 类中实现,采用 JDK proxy 代理仍是使用 cglib 代理,在这个方法中决定
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() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
isOptimize
方法就是返回 ProxyFactory 的 optimize 属性,为布尔值
是否执行积极优化的含义。
优化一般意味着,在代理建立后,通知的变化不会带来影响,默认下为 false。
optimize 在此处也被做为了一个判断依据。
optimize 能够参考文章:https://blog.csdn.net/zh199609/article/details/79710846
isProxyTargetClass
方法拿的则是 ProxyFactory 的 proxyTargetClass 属性,前面已经跟踪过。
hasNoUserSuppliedProxyInterfaces
方法在代理接口不存在,或者只有一个且是 SpringProxy 接口的子接口状况下,才返回 true 。
当上述三个方法都返回 false 时,代理才走的 JDK proxy 代理,也就是接口代理。
当知足其中一个条件,进入方法后,还有一层筛选,要么 target Class 是一个接口,要么是 Proxy 类的子类,不然其他状况都使用 cglib 代理,也就是类代理。
最后调用代理的 getProxy 方法。不一样代理的实现,其实就是spring对 JDK 的 Proxy,或者 cglib 的 Enhancer 的封装。最终完成AOP的实现。