1 前言
我们看过Spring对AOP配置的解析以及通知器的筛选,也看过了动态代理的实现,这节那我们就看下Spring创建代理的过程,为下节看代理具体的执行过程做铺垫哈。
那我们从哪看起呢?还记得创建代理的那个切入时机么?也就是这里
那么让我们开始看createProxy。
2 源码分析
2.1 方法通读
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { // 略过 暂时先不看 if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 创建了ProxyFactory代理工厂 看来我们的代理应该是交给这个工厂给我们生成了 ProxyFactory proxyFactory = new ProxyFactory(); // proxyFactory属性初始化 告诉他应该用什么样的代理方式 比如是jdk还是cglib proxyFactory.copyFrom(this); /** * 下边一大段都是在判断是否要将proxyTargetClass设置为true 但是不管设置的是true还是false 最后都是由DefaultAopProxyFactory进行代理创建决定用哪种方式创建 最后看这个方法 * proxyTargetClass 这个属性的的默认值是false 但是通过上边的copyFrom 值已经被覆盖了一次 而上边的值我们可以 * @EnableAspectJAutoProxy(proxyTargetClass = true) * <aop:aspectj-autoproxy proxy-target-class="true" /> 通过这两种方式更改 默认当然也是为false */ if (proxyFactory.isProxyTargetClass()) { // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios) if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) { // Must allow for introductions; can't just set interfaces to the proxy's interfaces only. for (Class<?> ifc : beanClass.getInterfaces()) { proxyFactory.addInterface(ifc); } } } else { // 又是在判断是否需要讲setProxyTargetClass = true 具体我没看哈 主要是我不知道他判断的依据是个什么原理 // No proxyTargetClass flag enforced, let's apply our default checks... if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { // 还是在判断是否需要讲setProxyTargetClass = true 具体我没看哈 主要是我不知道他判断的依据是个什么原理 evaluateProxyInterfaces(beanClass, proxyFactory); } } /** * 构建一个 Advisor 列表 问:specificInterceptors是个啥? * 答:getAdvicesAndAdvisorsForBean()方法的结果 就是当前bean筛选后的通知器Advisors * 问:Advisor是个啥? 答:可以理解为就是切点+通知 * buildAdvisors估计是要再进行加工一下 猜的哈 */ Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); // 设置proxyFactory工厂的通知其数组 proxyFactory.addAdvisors(advisors); // 设置proxyFactory工厂的targetSource proxyFactory.setTargetSource(targetSource); // 空方法用于自定义扩展 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 加载器的变换 略过 // Use original ClassLoader if bean class not locally loaded in overriding class loader ClassLoader classLoader = getProxyClassLoader(); if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) { classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader(); } // 调用工厂创建代理对象 return proxyFactory.getProxy(classLoader); }
看完创建代理的方法,大概总结下执行的几个关键步骤:
- 创建代理工厂对象
- 代理工厂属性初始化
- 判断是否将工厂的proxyTargetClass设置为true
- buildAdvisors根据bean名称和bean筛选后的通知器重新打包构建通知其数组
- 调用工厂创建代理对象
那么接下来我们重点看下4、5两个步骤。
2.2 buildAdvisors
/** * * @param beanName bean名称 * @param specificInterceptors 筛选后的通知器 * @return */ protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) { // 公共的通知器 Advisor[] commonInterceptors = resolveInterceptorNames(); // 将参数的通知器和公共的通知器都合并到allInterceptors List<Object> allInterceptors = new ArrayList<>(); if (specificInterceptors != null) { if (specificInterceptors.length > 0) { allInterceptors.addAll(Arrays.asList(specificInterceptors)); } if (commonInterceptors.length > 0) { if (this.applyCommonInterceptorsFirst) { allInterceptors.addAll(0, Arrays.asList(commonInterceptors)); } else { allInterceptors.addAll(Arrays.asList(commonInterceptors)); } } } if (logger.isTraceEnabled()) { int nrOfCommonInterceptors = commonInterceptors.length; int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0); logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors"); } Advisor[] advisors = new Advisor[allInterceptors.size()]; for (int i = 0; i < allInterceptors.size(); i++) { // wrap对每个通知器进行打包,那我们看下wrap advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); } return advisors; }
里边事情比较简单,就是把参数的通知器和公共的通知器进行合并,然后对每个通知器进行wrap,那我们看下wrap里都干了些什么。
private final List<AdvisorAdapter> adapters = new ArrayList<>(3); // 默认的3个适配器 /** * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters. */ public DefaultAdvisorAdapterRegistry() { registerAdvisorAdapter(new MethodBeforeAdviceAdapter()); registerAdvisorAdapter(new AfterReturningAdviceAdapter()); registerAdvisorAdapter(new ThrowsAdviceAdapter()); } @Override public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { // 本身是不是Advisor 是的话不需要再装饰了 直接返回 if (adviceObject instanceof Advisor) { return (Advisor) adviceObject; } // 不是Advice通知,直接报错 if (!(adviceObject instanceof Advice)) { throw new UnknownAdviceTypeException(adviceObject); } Advice advice = (Advice) adviceObject; // 是Advice 并且是个MethodInterceptor方法型拦截器 就用DefaultPointcutAdvisor给他包起来 if (advice instanceof MethodInterceptor) { // So well-known it doesn't even need an adapter. return new DefaultPointcutAdvisor(advice); } // 否则 通过适配器进行转换 上边有3个默认的适配器 for (AdvisorAdapter adapter : this.adapters) { /** * 调用adapter的supportsAdvice方法,判断遍历到的适配器是不是与当前的拦截器适配, * 如果得到结果true,则将拦截器封装为 DefaultPointcutAdvisor 返回。 * 如果adapters中没有能够预知适配的适配器,则表示无法将当前的拦截器包装成 Advisor,会在wrap方法的最后抛出异常。 */ if (adapter.supportsAdvice(advice)) { return new DefaultPointcutAdvisor(advice); } } throw new UnknownAdviceTypeException(advice); }
主要是根据类型进行做了判断,如果本身就是Advisor就直接返回了,是Advice的话通过三个适配器进行匹配转换,如果转换失败或者不是Advisor和Advice类型的话直接报错结束,好了,接下来我们看下创建代理。
2.3 proxyFactory.getProxy(classLoader)创建代理
/** * createAopProxy().getProxy(classLoader) 慢点看 * createAopProxy() 返回的是JdkDynamicAopProxy或者ObjenesisCglibAopProxy对象 也就是jdk代理或者cglib代理 * 然后调用他们的getProxy返回代理对象哈 * @param classLoader * @return */ public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
/** * Create a new ProxyCreatorSupport instance. */ public ProxyCreatorSupport() { // 默认工厂DefaultAopProxyFactory this.aopProxyFactory = new DefaultAopProxyFactory(); } /** * Return the AopProxyFactory that this ProxyConfig uses. */ public AopProxyFactory getAopProxyFactory() { return this.aopProxyFactory; } /** * 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. */ protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // 默认工厂createAopProxy return getAopProxyFactory().createAopProxy(this);
最后其实就是调用DefaultAopProxyFactory的getAopProxyFactory(),来返回一个jdk类对象或者cglib对象,那么让我们来看下。
/** * 最后由这家伙 决定是创建jdk还是cglib的代理 * @param config the AOP configuration in the form of an * AdvisedSupport object * @return * @throws AopConfigException */ @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { /** * 一个一个条件看哈 * NativeDetector.inNativeImage() 这个是啥 用于判断当前程序是否运行在GraalVM上(类似JVM),是否使用GVM编译,一般为false;如果是着这种情况,就只能只用JDK动态代理 * config.isOptimize(),这里的config是方法参数传入的,其实就是之前创建的 ProxyFactory 工厂对象,它的optimize属性是 ProxyFactory 创建后,通过copyFrom方法从后处理器中复制的属性值,它的默认值是false。 * config.isProxyTargetClass():是否是基于类的代理,如果想使用cglib代理,则设此值为true,但是不一定设置了就能用,你看下边还有个判断 * hasNoUserSuppliedProxyInterfaces():如果存在一个接口,还是SpringProxy类型的,就返回true,否则就是false,自定义的肯定是false,如果没接口也是false。一般为false; */ if (!NativeDetector.inNativeImage() && (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."); } /** * 目标类是接口 或者是本身是个代理类 或者是个lambda表达式 就用jdk代理 */ if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
最后就是这个方法决定是创建什么样的代理,看网上说的proxyTargetClass只要置为true就必须用cglib代理么,可能是版本不同哈,我这个版本的你看下边还有个判断,如果是接口它还是走的jdk代理了哈。
2.4 JDK动态代理的getProxy()和实例化方法
我暂时只看了JDK动态代理的哈,cglib的暂时没看。
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException { Assert.notNull(config, "AdvisedSupport must not be null"); if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { throw new AopConfigException("No advisors and no TargetSource specified"); } this.advised = config; this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces); } @Override public Object getProxy() { return getProxy(ClassUtils.getDefaultClassLoader()); } @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } /** * 是不是很熟悉的感觉 * 三个参数 类加载器 接口数组proxiedInterfaces 还有InvocationHandler实现 * 接口数组咋来的的? 实例化的时候是不是传了AdvisedSupport 这个里边是不是那会创建过程里有我们的advisors、接口等信息 是不是 想不起来的话回去再看一遍哈 * InvocationHandler实现 它传的自己说明它实现了InvocationHandler 就有invoke方法 就在下边是不是 我们下节讲通知器链执行过程的时候 会分析这个invoke方法 */ return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this); }
3 小结
好了,创建代理的过程我们也看了,主要是看了JDK的创建过程哈,现在就剩下invoke里的东西了,也就是我们的通知器数组是怎么串联起来执行的,下节我们讲这个。
理解哪里不对的地方,欢迎指正哈,加油。
标签:return,Spring,Advisor,代理,源码,proxyFactory,AOP,new,config From: https://www.cnblogs.com/kukuxjx/p/17139596.html