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