zoukankan      html  css  js  c++  java
  • Springboot中注解@Configuration源码分析

    Springboot中注解@Configuration和@Component的区别

    1.先说结论,@Configuration注解上面有@Component注解,所以@Component有的功能@Configuration都有。@Configuration生成的bean是一个代理对象,具体@Configuration的实现如何我们现在就打开源码来看看它。

    2.博客的代码路径:代码路径

    生成的代理类class文件路径:generate-class.zip

    你自己执行工程也会在target/classes/generate-class目录下生成代理类class代码

    3.@Configuration源码分析

    由于@SpringBootApplication注解上有@Configuration,为了代码简单,我们就直接看主类SpringbootconfigurationApplication就可以了。

    @Configuration注解的类会进入ConfigurationClassPostProcessor.enhanceConfigurationClasses方法去生成代理类。

    	public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    		......
    		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
    		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
    			AbstractBeanDefinition beanDef = entry.getValue();
    			// If a @Configuration class gets proxied, always proxy the target class
    			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
    			// Set enhanced subclass of the user-specified bean class
                //configClass就是原始的类
    			Class<?> configClass = beanDef.getBeanClass();
                //enhancedClass就是生成的代理类
    			Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
    			if (configClass != enhancedClass) {
    				if (logger.isTraceEnabled()) {
    					logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
    							"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
    				}
    				beanDef.setBeanClass(enhancedClass);
    			}
    		}
    		enhanceConfigClasses.tag("classCount", () -> String.valueOf(configBeanDefs.keySet().size())).end();
    	}
    

    生成代理类主要就是enhancer.enhance(configClass, this.beanClassLoader)这句了,下面我们自己去看看

    	public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
    		......
            //关键代码也就这一行了,首先创建一个Enhancer对象,然后调用createClass方法
    		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
    		......
    		return enhancedClass;
    	}
    
    	private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
    		Enhancer enhancer = new Enhancer();
            //设置生成代理类的父类,就是我们原始的类
    		enhancer.setSuperclass(configSuperClass);
            //设置代理类实现的接口
    		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
    		enhancer.setUseFactory(false);
            //设置代理类名的生成策略
    		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            //设置代理类的生成策略
    		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
            //设置代理类要重写的方法,对类中@Bean的方法和对实现了BeanFactoryAware接口的setBeanFactory进行重写,也就是代理
    		enhancer.setCallbackFilter(CALLBACK_FILTER);
    		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
    		return enhancer;
    	}
    

    在这里我们还需要Enhancer类中的属性KEY_FACTORY,由于它是静态属性,所以在加载Enhancer类的时候就会执行下面的代码

    	//代理类会实现EnhancerKey接口,继承KeyFactory(KEY_FACTORY是代理类的对象)
    	private static final EnhancerKey ,KEY_FACTORY =
    			(EnhancerKey) KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);
    

    这个KEY_FACTORY其实也是一个代理类的实例。我们就先看看它吧,这个主要是生成缓存的key,不感兴趣也可以跳过下面KEY_FACTORY的生成部分

    KEY_FACTORY的生成

    	public static KeyFactory create(ClassLoader loader, Class keyInterface, KeyFactoryCustomizer customizer,
    			List<KeyFactoryCustomizer> next) {
    		Generator gen = new Generator();
    		gen.setInterface(keyInterface);
    		// SPRING PATCH BEGIN
    		gen.setContextClass(keyInterface);
    		// SPRING PATCH END
    
    		if (customizer != null) {
    			gen.addCustomizer(customizer);
    		}
    		if (next != null && !next.isEmpty()) {
    			for (KeyFactoryCustomizer keyFactoryCustomizer : next) {
    				gen.addCustomizer(keyFactoryCustomizer);
    			}
    		}
    		gen.setClassLoader(loader);
            //主要是这句,我们继续走进去看看
    		return gen.create();
    	}
    
    
    		public KeyFactory create() {
    			//这里是设置类名的前缀
    			setNamePrefix(keyInterface.getName());
    			//继续跟进去
    			return (KeyFactory) super.create(keyInterface.getName());
    		}
    
    	protected Object create(Object key) {
    		try {
                //这里有个二级缓存,首先根据getClassLoader()去找,然后根据ClassLoaderData的lambda表达式GET_KEY去找,这里就是入参key了
    			ClassLoader loader = getClassLoader();
    			Map<ClassLoader, ClassLoaderData> cache = CACHE;
    			ClassLoaderData data = cache.get(loader);
    			if (data == null) {
    				synchronized (AbstractClassGenerator.class) {
    					cache = CACHE;
    					data = cache.get(loader);
    					if (data == null) {
    						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
    						data = new ClassLoaderData(loader);
    						newCache.put(loader, data);
    						CACHE = newCache;
    					}
    				}
    			}
    			this.key = key;
                //这里就会生成真正的类,我们走进去
    			Object obj = data.get(this, getUseCache());
    			if (obj instanceof Class) {
                    //在这里生成代理类的对象
    				return firstInstance((Class) obj);
    			}
    			return nextInstance(obj);
    		}
    		catch (RuntimeException | Error ex) {
    			throw ex;
    		}
    		catch (Exception ex) {
    			throw new CodeGenerationException(ex);
    		}
    	}
    

    这就会走到AbstractClassGenerator.ClassLoaderData的get方法

    		public Object get(AbstractClassGenerator gen, boolean useCache) {
    			if (!useCache) {
    				return gen.generate(ClassLoaderData.this);
    			}
    			else {
                    //我们传入的useCache是true,会走这里,再进去
    				Object cachedValue = generatedClasses.get(gen);
    				return gen.unwrapCachedValue(cachedValue);
    			}
    		}
    

    现在走到了LoadingCache.get方法

        public V get(K key) {
            	//这里的cacheKey就是org.springframework.cglib.proxy.Enhancer$EnhancerKey
            KK cacheKey = this.keyMapper.apply(key);
            Object v = this.map.get(cacheKey);
            我们这里是第一次创建,所以会走到 this.createEntry(key, cacheKey, v)
            return v != null && !(v instanceof FutureTask) ? v : this.createEntry(key, cacheKey, v);
        }
    

    ···

    protected V createEntry(final K key, KK cacheKey, Object v) {
        boolean creator = false;
        FutureTask task;
        Object result;
        if (v != null) {
            task = (FutureTask)v;
        } else {
            task = new FutureTask(new Callable<V>() {
                public V call() throws Exception {
                    //真正的执行会在这里,这里会是一个单独的线程,LoadingCache.this.loader是在ClassLoaderData的构造方法定义的lambda表达式,我们进去看看
                    return LoadingCache.this.loader.apply(key);
                }
            });
            result = this.map.putIfAbsent(cacheKey, task);
            if (result == null) {
                creator = true;
                //在这里开启线程调用
                task.run();
            } else {
                if (!(result instanceof FutureTask)) {
                    return result;
                }
    
                task = (FutureTask)result;
            }
        }
    
        try {
            //在这里挂起,等待线程返回结果
            result = task.get();
        } catch (InterruptedException var9) {
            throw new IllegalStateException("Interrupted while loading cache item", var9);
        } catch (ExecutionException var10) {
            Throwable cause = var10.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException)cause;
            }
    
            throw new IllegalStateException("Unable to load cache item", cause);
        }
    
        if (creator) {
            //创建成功,就会在这里加入到缓存中
            this.map.put(cacheKey, result);
        }
    
        return result;
    }
    
    			Function<AbstractClassGenerator, Object> load =
    					new Function<AbstractClassGenerator, Object>() {
    						public Object apply(AbstractClassGenerator gen) {
                                //这里又会回到KeyFactory.Generator这个内部类中,这个方法在它的父类AbstractClassGenerator中,我们走进去
    							Class klass = gen.generate(ClassLoaderData.this);
    							return gen.wrapCachedClass(klass);
    						}
    					};
    

    AbstractClassGenerator的generate方法

    protected Class generate(ClassLoaderData data) {
    			......
    		try {
    			......
    			synchronized (classLoader) {
    				//这里生成类的名字
    				String name = generateClassName(data.getUniqueNamePredicate());
    				data.reserveName(name);
    				this.setClassName(name);
    			}
    			......
    			//在这里生成类的byte[]文件,继续走进去
    			byte[] b = strategy.generate(this);
                //这个是从字节码中获取类名
                //在工程springbootconfiguration	argetclassesgenerate-class这个目录下,根据className+".class"就能找到我们生成的class文件(注意将包名的.换成路径分割线)
    			String className = ClassNameReader.getClassName(new ClassReader(b));
    			ProtectionDomain protectionDomain = getProtectionDomain();
    			synchronized (classLoader) { // just in case
    				// SPRING PATCH BEGIN
    				//将生成的类的文件加载进jvm
    				gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
    				// SPRING PATCH END
    			}
    			return gen;
    		}
    		......
    	}
    

    DefaultGeneratorStrategy的generate方法

        //真正生成类文件的代码就在这里,这个是通过asm来生成的,具体asm这块就不再往里面看了,关于asm这块是个单独的知识点,不过对我们来说,不看里面细节也不影响我们的分析,我们main方法中有 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,p);,就会将生成的class文件保存到本地,我们直接看这个就好了,我们当前生成的class文件统一放到了springbootconfiguration	argetclassesgenerate-class这个目录下
        public byte[] generate(ClassGenerator cg) throws Exception {
            DebuggingClassWriter cw = this.getClassVisitor();
            this.transform(cg).generateClass(cw);
            return this.transform(cw.toByteArray());
        }
    
    

    下面这个就是我本地生成的class文件反编译后的java代码

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package org.springframework.cglib.proxy;
    
    import org.springframework.asm.Type;
    import org.springframework.cglib.core.KeyFactory;
    import org.springframework.cglib.core.WeakCacheKey;
    import org.springframework.cglib.proxy.Enhancer.EnhancerKey;
    
    public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f extends KeyFactory implements EnhancerKey {
        private final String FIELD_0;
        private final String[] FIELD_1;
        private final WeakCacheKey FIELD_2;
        private final Type[] FIELD_3;
        private final boolean FIELD_4;
        private final boolean FIELD_5;
        private final Long FIELD_6;
    
        public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f() {
        }
    
        public Object newInstance(String var1, String[] var2, WeakCacheKey var3, Type[] var4, boolean var5, boolean var6, Long var7) {
            return new Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f(var1, var2, var3, var4, var5, var6, var7);
        }
    
        public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f(String var1, String[] var2, WeakCacheKey var3, Type[] var4, boolean var5, boolean var6, Long var7) {
            this.FIELD_0 = var1;
            this.FIELD_1 = var2;
            this.FIELD_2 = var3;
            this.FIELD_3 = var4;
            this.FIELD_4 = var5;
            this.FIELD_5 = var6;
            this.FIELD_6 = var7;
        }
    
        public int hashCode() {
            int var10002 = 1213 * 1209107;
            String var10001 = this.FIELD_0;
            int var10000 = var10002 + (var10001 != null ? var10001.hashCode() : 0);
            String[] var5 = this.FIELD_1;
            if (var5 != null) {
                String[] var1 = var5;
    
                for(int var2 = 0; var2 < var1.length; ++var2) {
                    var10000 = var10000 * 1209107 + (var1[var2] != null ? var1[var2].hashCode() : 0);
                }
            }
    
            var10002 = var10000 * 1209107;
            WeakCacheKey var6 = this.FIELD_2;
            var10000 = var10002 + (var6 != null ? var6.hashCode() : 0);
            Type[] var7 = this.FIELD_3;
            if (var7 != null) {
                Type[] var3 = var7;
    
                for(int var4 = 0; var4 < var3.length; ++var4) {
                    var10000 = var10000 * 1209107 + (var3[var4] != null ? var3[var4].hashCode() : 0);
                }
            }
    
            var10002 = ((var10000 * 1209107 + (this.FIELD_4 ^ 1)) * 1209107 + (this.FIELD_5 ^ 1)) * 1209107;
            Long var8 = this.FIELD_6;
            return var10002 + (var8 != null ? var8.hashCode() : 0);
        }
    
        public boolean equals(Object var1) {
            if (var1 instanceof Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f) {
                String var10000 = this.FIELD_0;
                String var10001 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_0;
                if (var10001 == null) {
                    if (var10000 != null) {
                        return false;
                    }
                } else if (var10000 == null || !var10000.equals(var10001)) {
                    return false;
                }
    
                String[] var8 = this.FIELD_1;
                String[] var10 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_1;
                if (var10 == null) {
                    if (var8 != null) {
                        return false;
                    }
                } else {
                    label178: {
                        if (var8 != null) {
                            if (var10.length == var8.length) {
                                String[] var2 = var10;
                                String[] var3 = var8;
                                int var4 = 0;
    
                                while(true) {
                                    if (var4 >= var2.length) {
                                        break label178;
                                    }
    
                                    var10000 = var2[var4];
                                    var10001 = var3[var4];
                                    if (var3[var4] == null) {
                                        if (var10000 != null) {
                                            return false;
                                        }
                                    } else if (var10000 == null || !var10000.equals(var10001)) {
                                        return false;
                                    }
    
                                    ++var4;
                                }
                            }
                        }
    
                        return false;
                    }
                }
    
                WeakCacheKey var9 = this.FIELD_2;
                WeakCacheKey var13 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_2;
                if (var13 == null) {
                    if (var9 != null) {
                        return false;
                    }
                } else if (var9 == null || !var9.equals(var13)) {
                    return false;
                }
    
                Type[] var11 = this.FIELD_3;
                Type[] var15 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_3;
                if (var15 == null) {
                    if (var11 != null) {
                        return false;
                    }
                } else {
                    if (var11 == null) {
                        return false;
                    }
    
                    if (var15.length != var11.length) {
                        return false;
                    }
    
                    Type[] var5 = var15;
                    Type[] var6 = var11;
    
                    for(int var7 = 0; var7 < var5.length; ++var7) {
                        Type var12 = var5[var7];
                        Type var16 = var6[var7];
                        if (var6[var7] == null) {
                            if (var12 != null) {
                                return false;
                            }
                        } else if (var12 == null || !var12.equals(var16)) {
                            return false;
                        }
                    }
                }
    
                if (this.FIELD_4 == ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_4 && this.FIELD_5 == ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_5) {
                    Long var14 = this.FIELD_6;
                    Long var17 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f)var1).FIELD_6;
                    if (var17 == null) {
                        if (var14 == null) {
                            return true;
                        }
                    } else if (var14 != null && var14.equals(var17)) {
                        return true;
                    }
                }
            }
    
            return false;
        }
    
        public String toString() {
            StringBuffer var10000 = new StringBuffer();
            String var10001 = this.FIELD_0;
            var10000 = (var10001 != null ? var10000.append(var10001.toString()) : var10000.append("null")).append(", ");
            String[] var6 = this.FIELD_1;
            if (var6 != null) {
                var10000 = var10000.append("{");
                String[] var1 = var6;
    
                for(int var2 = 0; var2 < var1.length; ++var2) {
                    var10000 = (var1[var2] != null ? var10000.append(var1[var2].toString()) : var10000.append("null")).append(", ");
                }
    
                var10000.setLength(var10000.length() - 2);
                var10000 = var10000.append("}");
            } else {
                var10000 = var10000.append("null");
            }
    
            var10000 = var10000.append(", ");
            WeakCacheKey var9 = this.FIELD_2;
            var10000 = (var9 != null ? var10000.append(var9.toString()) : var10000.append("null")).append(", ");
            Type[] var10 = this.FIELD_3;
            if (var10 != null) {
                var10000 = var10000.append("{");
                Type[] var3 = var10;
    
                for(int var4 = 0; var4 < var3.length; ++var4) {
                    var10000 = (var3[var4] != null ? var10000.append(var3[var4].toString()) : var10000.append("null")).append(", ");
                }
    
                var10000.setLength(var10000.length() - 2);
                var10000 = var10000.append("}");
            } else {
                var10000 = var10000.append("null");
            }
    
            var10000 = var10000.append(", ").append(this.FIELD_4).append(", ").append(this.FIELD_5).append(", ");
            Long var13 = this.FIELD_6;
            return (var13 != null ? var10000.append(var13.toString()) : var10000.append("null")).toString();
        }
    }
    
    

    生成代理类调用的还是create方法中的代码

    	protected Object create(Object key) {
    			......
    			if (obj instanceof Class) {
                    //在这里生成代理类的对象,调用代理类的无参构造方法生成代理类的对象
    				return firstInstance((Class) obj);
    			}
    			return nextInstance(obj);
    		}
    		catch (RuntimeException | Error ex) {
    			throw ex;
    		}
    		catch (Exception ex) {
    			throw new CodeGenerationException(ex);
    		}
    	}
    

    下面就是我本地生成的KEY_FACTORY对象

    下面我们看看生成@Configuration代理类的代码

    我们回到ConfigurationClassEnhancer的createClass方法,对这个不感兴趣,也可以跳过这部分,直接看初始化@Configuration代理类部分

    	private Class<?> createClass(Enhancer enhancer) {
    		//这里直接调用Enhancer的createClass方法,继续走进去
    		Class<?> subclass = enhancer.createClass();
    		......
    	}
    

    Enhancer中会继续调到createHelper方法

    	private Object createHelper() {
    		preValidate();
    		//这就是根据上面生成代理类的对象生成key,根据这个key在缓存中查找
    		Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
    				ReflectUtils.getNames(interfaces),
    				filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
    				callbackTypes,
    				useFactory,
    				interceptDuringConstruction,
    				serialVersionUID);
    		this.currentKey = key;
    		Object result = super.create(key);
    		return result;
    	}
    

    后面很多代码都和上面KEY_FACTORY的生成是一样的,主要是这里会对方法进行一些过滤

    生成代理类的时候具体要ConfigurationClassEnhancer.CALLBACK_FILTER确定代理方法的生成器

    CALLBACK_FILTER中根据CALLBACKS来进行过滤,由于BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor都是实现了MethodInterceptor, ConditionalCallback这两个接口,CALLBACK_FILTER中就会直接使用ConditionalCallback.isMatch去判断,其他的都会由NoOp.INSTANCE来处理。

    BeanMethodInterceptor方法会过滤出来有@注解的方法,BeanFactoryAwareMethodInterceptor会过滤出来BeanFactoryAware.setBeanFactory方法

    具体方法的生成器是在CallbackInfo中定义的

        static {
            CALLBACKS = new CallbackInfo[]{new CallbackInfo(NoOp.class, NoOpGenerator.INSTANCE), new CallbackInfo(MethodInterceptor.class, MethodInterceptorGenerator.INSTANCE), new CallbackInfo(InvocationHandler.class, InvocationHandlerGenerator.INSTANCE), new CallbackInfo(LazyLoader.class, LazyLoaderGenerator.INSTANCE), new CallbackInfo(Dispatcher.class, DispatcherGenerator.INSTANCE), new CallbackInfo(FixedValue.class, FixedValueGenerator.INSTANCE), new CallbackInfo(ProxyRefDispatcher.class, DispatcherGenerator.PROXY_REF_INSTANCE)};
        }
    

    BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor这两个过滤器实现了MethodInterceptor接口,所以它们的方法生成器都是 MethodInterceptorGenerator.INSTANCE(会处理@注解的方法,BeanFactoryAwareMethodInterceptor会过滤出来BeanFactoryAware.setBeanFactory方法)

    其他的都是由NoOp.INSTANCE来处理,方法生成器就是NoOpGenerator.INSTANCE(这个方法实际不会去生成字节码,所以直接上这些方法还是调用父类的方法)

    最终生成的字节码是这个样子的

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package com.example.springbootconfiguration;
    
    import com.example.springbootconfiguration.entity.Home;
    import com.example.springbootconfiguration.entity.User;
    import java.lang.reflect.Method;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.cglib.core.ReflectUtils;
    import org.springframework.cglib.core.Signature;
    import org.springframework.cglib.proxy.Callback;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    import org.springframework.cglib.proxy.NoOp;
    import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration;
    
    public class SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc extends SpringbootconfigurationApplication implements EnhancedConfiguration {
        private boolean CGLIB$BOUND;
        public static Object CGLIB$FACTORY_DATA;
        private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
        private static final Callback[] CGLIB$STATIC_CALLBACKS;
        private MethodInterceptor CGLIB$CALLBACK_0;
        private MethodInterceptor CGLIB$CALLBACK_1;
        private NoOp CGLIB$CALLBACK_2;
        private static Object CGLIB$CALLBACK_FILTER;
        private static final Method CGLIB$getUser$0$Method;
        private static final MethodProxy CGLIB$getUser$0$Proxy;
        private static final Object[] CGLIB$emptyArgs;
        private static final Method CGLIB$getHome$1$Method;
        private static final MethodProxy CGLIB$getHome$1$Proxy;
        private static final Method CGLIB$setBeanFactory$6$Method;
        private static final MethodProxy CGLIB$setBeanFactory$6$Proxy;
        public BeanFactory $$beanFactory;
    
        static void CGLIB$STATICHOOK1() {
            CGLIB$THREAD_CALLBACKS = new ThreadLocal();
            CGLIB$emptyArgs = new Object[0];
            Class var0 = Class.forName("com.example.springbootconfiguration.SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc");
            Class var1;
            CGLIB$setBeanFactory$6$Method = ReflectUtils.findMethods(new String[]{"setBeanFactory", "(Lorg/springframework/beans/factory/BeanFactory;)V"}, (var1 = Class.forName("org.springframework.beans.factory.BeanFactoryAware")).getDeclaredMethods())[0];
            CGLIB$setBeanFactory$6$Proxy = MethodProxy.create(var1, var0, "(Lorg/springframework/beans/factory/BeanFactory;)V", "setBeanFactory", "CGLIB$setBeanFactory$6");
            Method[] var10000 = ReflectUtils.findMethods(new String[]{"getUser", "()Lcom/example/springbootconfiguration/entity/User;", "getHome", "()Lcom/example/springbootconfiguration/entity/Home;"}, (var1 = Class.forName("com.example.springbootconfiguration.SpringbootconfigurationApplication")).getDeclaredMethods());
            CGLIB$getUser$0$Method = var10000[0];
            CGLIB$getUser$0$Proxy = MethodProxy.create(var1, var0, "()Lcom/example/springbootconfiguration/entity/User;", "getUser", "CGLIB$getUser$0");
            CGLIB$getHome$1$Method = var10000[1];
            CGLIB$getHome$1$Proxy = MethodProxy.create(var1, var0, "()Lcom/example/springbootconfiguration/entity/Home;", "getHome", "CGLIB$getHome$1");
        }
    
        final User CGLIB$getUser$0() {
            return super.getUser();
        }
    
        public final User getUser() {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }
    
            return var10000 != null ? (User)var10000.intercept(this, CGLIB$getUser$0$Method, CGLIB$emptyArgs, CGLIB$getUser$0$Proxy) : super.getUser();
        }
    
        final Home CGLIB$getHome$1() {
            return super.getHome();
        }
    
        public final Home getHome() {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }
    
            return var10000 != null ? (Home)var10000.intercept(this, CGLIB$getHome$1$Method, CGLIB$emptyArgs, CGLIB$getHome$1$Proxy) : super.getHome();
        }
    
        final void CGLIB$setBeanFactory$6(BeanFactory var1) throws BeansException {
            super.setBeanFactory(var1);
        }
    
        public final void setBeanFactory(BeanFactory var1) throws BeansException {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_1;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_1;
            }
    
            if (var10000 != null) {
                var10000.intercept(this, CGLIB$setBeanFactory$6$Method, new Object[]{var1}, CGLIB$setBeanFactory$6$Proxy);
            } else {
                super.setBeanFactory(var1);
            }
        }
    
        public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
            String var10000 = var0.toString();
            switch(var10000.hashCode()) {
            case -964783719:
                if (var10000.equals("getUser()Lcom/example/springbootconfiguration/entity/User;")) {
                    return CGLIB$getUser$0$Proxy;
                }
                break;
            case 1508184433:
                if (var10000.equals("getHome()Lcom/example/springbootconfiguration/entity/Home;")) {
                    return CGLIB$getHome$1$Proxy;
                }
                break;
            case 2095635076:
                if (var10000.equals("setBeanFactory(Lorg/springframework/beans/factory/BeanFactory;)V")) {
                    return CGLIB$setBeanFactory$6$Proxy;
                }
            }
    
            return null;
        }
    
        public SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc() {
            CGLIB$BIND_CALLBACKS(this);
        }
    
        public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
            CGLIB$THREAD_CALLBACKS.set(var0);
        }
    
        public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
            CGLIB$STATIC_CALLBACKS = var0;
        }
    
        private static final void CGLIB$BIND_CALLBACKS(Object var0) {
            SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc var1 = (SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc)var0;
            if (!var1.CGLIB$BOUND) {
                var1.CGLIB$BOUND = true;
                Object var10000 = CGLIB$THREAD_CALLBACKS.get();
                if (var10000 == null) {
                    var10000 = CGLIB$STATIC_CALLBACKS;
                    if (var10000 == null) {
                        return;
                    }
                }
    
                Callback[] var10001 = (Callback[])var10000;
                var1.CGLIB$CALLBACK_2 = (NoOp)((Callback[])var10000)[2];
                var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1];
                var1.CGLIB$CALLBACK_0 = (MethodInterceptor)var10001[0];
            }
    
        }
    
        static {
            CGLIB$STATICHOOK2();
            CGLIB$STATICHOOK1();
        }
    
        static void CGLIB$STATICHOOK2() {
        }
    }
    
    

    初始化@Configuration代理类

    在上面生成了代理类字节码之后,就会将代理类字节码加载到jvm,生成代理类。

    由于代理类中有static 静态代码块,所以这时就会去执行静态代码块(上面153行代码)

    CGLIB$STATICHOOK2()的实现在158行,CGLIB$STATICHOOK1()的实现在39行,具体就不仔细看了。

    执行完类加载后,会返回到ConfigurationClassEnhancer的createClass方法

    	private Class<?> createClass(Enhancer enhancer) {
            //这里就是生成代理类并加载
    		Class<?> subclass = enhancer.createClass();
    		// Registering callbacks statically (as opposed to thread-local)
    		// is critical for usage in an OSGi environment (SPR-5932)...
            //这时会执行到这里,会通过反射调用代理类的CGLIB$SET_STATIC_CALLBACKS(org.springframework.cglib.proxy.Callback[])方法将CALLBACKS设置上去,由于是静态方法,所以不需要实例化对象可以直接调用
    		Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
    		return subclass;
    	}
    

    到这里代理类就基本完成了,后面就是生成bean对象了。

    来生成对应bean的时候,会默认无参构造方法。

      public SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$d37254bc() {
            CGLIB$BIND_CALLBACKS(this);
        }
    

    在CGLIB$BIND_CALLBACKS中主要会设置CGLIB$CALLBACK_x

        private static final void CGLIB$BIND_CALLBACKS(Object var0) {
    			......
                Callback[] var10001 = (Callback[])var10000;
                var1.CGLIB$CALLBACK_2 = (NoOp)((Callback[])var10000)[2]; //NoOp.INSTANCE
                var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1];  //new BeanFactoryAwareMethodInterceptor()
                var1.CGLIB$CALLBACK_0 = (MethodInterceptor)var10001[0];  //new BeanMethodInterceptor()
            }
    
        }
    

    到这里由代理类生成的bean就完成了,下面我们看看方法上@Bean生成的

    生成代理类上@bean方法 表示的对象

    我们这里由两个@Bean的方法

        @Bean
        public User getUser() {
            return new User();
        }
    
        @Bean
        public Home getHome() {
            return new Home(getUser());
        }
    
    }
    

    我们先看getUser的执行吧

        public final User getUser() {
            //这里的var10000就是上面的new BeanMethodInterceptor()
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }
    		//所以这里会调用BeanMethodInterceptor.intercept进行返回
            return var10000 != null ? (User)var10000.intercept(this, CGLIB$getUser$0$Method, CGLIB$emptyArgs, CGLIB$getUser$0$Proxy) : super.getUser();
        }
    

    BeanMethodInterceptor.intercept方法

    public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
    					MethodProxy cglibMethodProxy) throws Throwable {
    			......	
    			//这里的beanMethod就是我们生成代理类的父类的getUser方法,当前beanFactory是正在创建它,所以会进到这个if分支,
    			if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
    				......
                    //这里使用代理类中CGLIB$STATICHOOK1方法生成的代理方法去继续调用,最终会调用代理类的CGLIB$getUser$1方法,继续调用到父类的getUser()方法
                   //在这调用过程中也会生成两个快速查找方法的类
                   //1.SpringbootconfigurationApplication$$FastClassBySpringCGLIB$$fae3d721.class在我们的原始类中快速查找方法
                   //2.SpringbootconfigurationApplication$$EnhancerBySpringCGLIB$$43375915$$FastClassBySpringCGLIB$$c293f4a3在代理类中快速查找方法     
    				return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
    			}
    
    			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
    		}
    
    

    下面我们来看看getHome的执行

        public final Home getHome() {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }
    
            return var10000 != null ? (Home)var10000.intercept(this, CGLIB$getHome$1$Method, CGLIB$emptyArgs, CGLIB$getHome$1$Proxy) : super.getHome();
        }
    

    还是调用BeanMethodInterceptor.intercept方法,前面的逻辑是和上面的一样的,也会调用到CGLIB$getHome$0方法,继续调用到父类的getHome();方法,这时由于父类getHome()方法中有调用getUser()方法,我们的代理类已经重写了这个方法,这时又会回到代理类中getUser()继而继续调用BeanMethodInterceptor.intercept方法

    		@Override
    		@Nullable
    		public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
    					MethodProxy cglibMethodProxy) throws Throwable {
    			......
                //由于beanFactory中我们正在创建的是getHome()这个方法,所以这时beanMethod=getUser()不会走到这个if分支
    			if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
    				......
    			}
    			//所以会执行到这里
    			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
    		}
    
    
    		private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
    				ConfigurableBeanFactory beanFactory, String beanName) {
    			......
    			try {
    				......
                    //由于之前已经执行过getUser 生成了bean对象,所以这里会从beanFactory中获取到对应的bean对象
    				Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
    						beanFactory.getBean(beanName));
                    ......
    				//后面这就是获取到当前正在创建的bean,添加依赖关系了
    				Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
    				if (currentlyInvoked != null) {
    					String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
    					beanFactory.registerDependentBean(beanName, outerBeanName);
    				}
    				return beanInstance;
    			}
    			finally {
    				if (alreadyInCreation) {
    					beanFactory.setCurrentlyInCreation(beanName, true);
    				}
    			}
    		}
    

    总结

    @Configuration注解会生成代理类,代理类会继承我的@Configuration注解所在的类,并实现EnhancedConfiguration接口。

    会对@Bean,BeanFactoryAware.setBeanFactory(EnhancedConfiguration继承了BeanFactoryAware接口)的方法在代理类中进行重写,并用BeanMethodInterceptor.intercept进行拦截增强,多次调用@Bean的方法实际是返回的同一个对象,第一次调用时会生成对象,之后的调用都是会从beanFactory中获取

  • 相关阅读:
    leetcode 309. Best Time to Buy and Sell Stock with Cooldown
    leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee
    leetcode 32. Longest Valid Parentheses
    leetcode 224. Basic Calculator
    leetcode 540. Single Element in a Sorted Array
    leetcode 109. Convert Sorted List to Binary Search Tree
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 84. Largest Rectangle in Histogram
    leetcode 338. Counting Bits
    git教程之回到过去,版本对比
  • 原文地址:https://www.cnblogs.com/wbo112/p/15058153.html
Copyright © 2011-2022 走看看