登录/注册
My Queen
788
占位
1
占位
1
浏览量
占位
粉丝
占位
关注
Springboot中注解@Configuration源码分析
My Queen
2021-09-06 15:42:32 2021-09-06
35
0

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\target\classes\generate-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\target\classes\generate-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中获取

原文: https://www.cnblogs.com/wbo112/p/15058153.html

暂无评论