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中获取

  • 相关阅读:
    Prototype的深度探索
    MySQL LIST分区
    CentOS6下Haproxy的安装配置
    haproxy做TCP层的负载均衡
    Shape Control for .NET
    如何通过 HSB 颜色模式构建夜间模式
    使用ICSharpCode.TextEditor制作一个语法高亮显示的XML编辑器
    Roslyn介绍
    信息安全名词
    用彩虹表破解MD5、LM Hash等复杂加密密码
  • 原文地址:https://www.cnblogs.com/wbo112/p/15058153.html
Copyright © 2011-2022 走看看