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\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对象

Springboot中注解@Configuration源码分析

下面我们看看生成@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确定代理方法的生成器

Springboot中注解@Configuration源码分析

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

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

Springboot中注解@Configuration源码分析

具体方法的生成器是在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中获取

上一篇:408算法练习——颜色分类(快排)


下一篇:VM虚拟机安装Windows Server 2008操作系统