Spring中@Configuration源码深度解析(二)

      在Spring中@Configuration源码深度解析(一)中已经说到了执行代码块4PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法的第一个重要方法: invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);会将普通注解类转换成beanDefinition对象。

      下面让我们说一下这个方法第二个重要方法:invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);该方法会执行实现了BeanFactoryPostProcessor接口的postProcessBeanFactory方法(由于ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,而BeanDefinitionRegistryPostProcessor 又继承了BeanFactoryPostProcessor接口,所以在这篇文章的重点是讲ConfigurationClassPostProcessor的postProcessBeanFactory方法)。

代码块1.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法

private static void invokeBeanFactoryPostProcessors(
		Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
	//执行所有BeanFactoryPostProcessor的postProcessBeanFactory方法
	for (BeanFactoryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanFactory(beanFactory);
	}
}

       该方法最终调用ConfigurationClassPostProcessor的postProcessBeanFactory方法,完成会加了@Configuration注解类的增强。

    代码块2.ConfigurationClassPostProcessor#postProcessBeanFactory方法

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	int factoryId = System.identityHashCode(beanFactory);
	if (this.factoriesPostProcessed.contains(factoryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + beanFactory);
	}
	this.factoriesPostProcessed.add(factoryId);
	if (!this.registriesPostProcessed.contains(factoryId)) {
		// BeanDefinitionRegistryPostProcessor hook apparently not supported...
		// Simply call processConfigurationClasses lazily at this point then.
		processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
	}
	//1. 给加了@Configuration注解的配置类产生cglib代理
	enhanceConfigurationClasses(beanFactory);
	//2. 向容器中注入ImportAwareBeanPostProcessor,其是一个bean的后置处理器,
	beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

      第1步:给加了@Configuration注解的配置类产生cglib代理 ,并给它设置成EnhancedConfiguration的子类,查看代码块3

      第2步:向容器中注入ImportAwareBeanPostProcessor,ImportAwareBeanPostProcessor是一个bean的后置处理器,其作用就是判断一个类是不是EnhancedConfiguration的子类,如果是把bean工厂赋值给他,这样加了@Configuration注解的类,就可以直接去容器中获取bean

代码块3. ConfigurationClassPostProcessor#enhanceConfigurationClasses方法

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
	//存放所有为full类型的BeanDefinition,也就是加了@Configuration注解的
	Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
	//1.从容器中拿到所有BeanDefinition的名称
	for (String beanName : beanFactory.getBeanDefinitionNames()) {
		BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
		//2.判断是否是一个全注解类
		//扫描是全注解类?full和lite的关系
		if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
			if (!(beanDef instanceof AbstractBeanDefinition)) {
				throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
						beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
			}
			//3.将为full类型的加到Map中
			configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
		}
	}
	//4.没有full类型的就返回
	if (configBeanDefs.isEmpty()) {
		// nothing to enhance -> return immediately
		return;
	}
	//创建一个增强器
	ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
	//5.遍历这个Map
	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);
		try {
			// Set enhanced subclass of the user-specified bean class
			// 6.获取类的Class进行增强
			Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
			if (configClass != null) {
				//7. 完成对全注解类的cglib代理
				Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
				if (configClass != enhancedClass) {
					//8.将增强后的cglib代理类设置成BeanDefinition的BeanClass
					beanDef.setBeanClass(enhancedClass);
				}
			}
		}
		catch (Throwable ex) {
			throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
		}
	}
}

      在第2步会判断是否是full类型的,如果去就加到一个Map中,看代码块4.

      在第7步中会完成会full类型的代理,使用的是cglib代理,这是你就知道了为什么加了@Configuration的类不能是final类型的了(使用cglib代理会继承需要增强的类,而你加了final说明这个类不能有子类了)看代码块5.

      第8步:将增强后的cglib代理类设置成BeanDefinition的beanClass,因为在后面Spring进行实例化bean的时候,是根据BeanDefinition的beanClass来进行的,所以在此将beanClass改了之后,就能在下面使用这个代理类来进行实例化。

代码块4:ConfigurationClassUtils#isFullConfigurationClass方法

    

public static boolean isFullConfigurationClass(BeanDefinition beanDef) {
    //判断BeanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性是不是full
	return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
}

      在Spring中@Configuration源码深度解析(一)中加了@Configuration注解的类会被设置成full,所以会被加入到configBeanDefs的Map中。

代码块5:ConfigurationClassEnhancer#enhance方法

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
	//1. isAssignableFrom方式是判断父类.class.isAssignableFrom(子类.class)
	//isAssignableFrom()方法是从类继承的角度去判断,是判断是否为某个类的父类
	//如果是EnhancedConfiguration的子类,说明被代理过
	if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
		return configClass;
	}
	
	//2. 没有被代理cglib代理,则进行cglib代理
	Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
	return enhancedClass;
}

       在第2步中有两个方法一个是newEnhancer方法(看代码块6),该方法是创建一个增强对象,一个是createClass方法,根据得到一个增强后的Class对象, 

       注意在newEnhancer方法会生成一个Enhancer对象,用于在createClass中进行得到一个增强后的Class对象

代码块6:ConfigurationClassEnhancer#newEnhancer方法

private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
	Enhancer enhancer = new Enhancer();
	//1. 增强父类,地球人都知道cglib是基于继承来的
	//设置需要被增强的对象为代理对象的父类
	enhancer.setSuperclass(configSuperClass);
	//2. 增强接口,为什么要增强接口?
	//便于判断,表示一个类以及被增强了,EnhancedConfiguration继承了BeanFactoryAware接口
	//所以代理类可以拿到BeanFactory工厂
	enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
	//不继承Factory接口
	enhancer.setUseFactory(false);
	enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	// 3. BeanFactoryAwareGeneratorStrategy是一个生成策略
	// 主要为生成的CGLIB类中添加成员变量$$beanFactory
	// 同时基于接口EnhancedConfiguration的父接口BeanFactoryAware中的setBeanFactory方法,
	// 设置此变量的值为当前Context中的beanFactory,这样一来我们这个cglib代理的对象就有了beanFactory
	//有了factory就能获得对象,而不用去通过方法获得对象了,因为通过方法获得对象不能控制器过程
	//该BeanFactory的作用是在this调用时拦截该调用,并直接在beanFactory中获得目标bean
	enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
	//4. 过滤方法,不能每次都去new
	enhancer.setCallbackFilter(CALLBACK_FILTER);
	enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
	return enhancer;
}

//该类为ConfigurationClassEnhancer的内部类,继承了BeanFactoryAware接口
public interface EnhancedConfiguration extends BeanFactoryAware {
}

       在第2步中会给代理类设置一个ConfigurationClassEnhancer的接口,这个接口继承了BeanFactoryAware,让生成的代理类可以拿到BeanFactory对象。

       在第3步中会给代理类增加一个public的类型为BeanFactory,名为$$beanFactory字段的属性,看代码块7

       在第4步增强方法拦截器,在执行方法的时候,首先去容器中判断是否有这个bean,如果没有的话,才会执行这个方法,有的话,直接返回容器内部的bean,看代码块8

代码块7: BeanFactoryAwareGeneratorStrategy类:

private static class BeanFactoryAwareGeneratorStrategy extends DefaultGeneratorStrategy {

	@Nullable
	private final ClassLoader classLoader;

	public BeanFactoryAwareGeneratorStrategy(@Nullable ClassLoader classLoader) {
		this.classLoader = classLoader;
	}
	@Override
	protected ClassGenerator transform(ClassGenerator cg) throws Exception {
		ClassEmitterTransformer transformer = new ClassEmitterTransformer() {
			@Override
			public void end_class() {
			    //给代理类设置public类型为BeanFactory,名称是$$beanFactory的属性
				//Constants.ACC_PUBLIC = 0x0001
				//BEAN_FACTORY_FIELD = "$$beanFactory"
				declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
				super.end_class();
			}
		};
		return new TransformingClassGenerator(cg, transformer);
	}
	
	//省略了一个方法
}

代码块8:看一下CALLBACK_FILTER

        

        在代码块6中的第4步,就是添加了CALLBACK_FILTER变量,然后这个两个里面有两个方法拦截器,一个是拦截标注了@Configuration注解的类里面的方法,一个是拦截BeanFactoryAware接口的setBeanFactory方法。

       对于拦截标注了@Configuration注解的类里面的方法,看代码块9

代码块9:ConfigurationClassEnhancer.BeanMethodInterceptor类

//ConfigurationClassEnhancer里面的内部类BeanMethodInterceptor
//用于拦截@Bean方法的调用,并直接从BeanFactory中获取目标bean,而不是通过执行方法。
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
	@Override
	@Nullable
	public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
				MethodProxy cglibMethodProxy) throws Throwable {

		//enhancedConfigInstance 代理
		// 1. 通过enhancedConfigInstance中cglib生成的成员变量$$beanFactory获得beanFactory。
		ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
		// 2. 获得@Configuration注解中加了@Bean的bean的名称,如果没有指定,则使用方法作为bean的名称
		String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

		// Determine whether this bean is a scoped-proxy
		Scope scope = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
		if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
			String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
			if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
				beanName = scopedBeanName;
			}
		}
               //3. 这里是将bean的名称加上"&"判断是不是FactoryBean类型的,如果是的话,就还需要对FactoryBean
	    //类型再进行一次代理,为什么?因为你获取的就是一个new出来的FactoryBean的,就不能保证单一性,
		//所以这这里需要对FactoryBean在进行一次拦截
		if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
				factoryContainsBean(beanFactory, beanName)) {
			Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
			if (factoryBean instanceof ScopedProxyFactoryBean) {
				// Scoped proxy factory beans are a special case and should not be further proxied
			}
			else {
				// It is a candidate FactoryBean - go ahead with enhancement
				return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
			}
		}

		//4. 一个非常牛逼的判断
		//判断到底是new 还是get
		//判断执行的方法和调用方法是不是同一个方法
		if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
			// The factory is calling the bean method in order to instantiate and register the bean
			// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
			// create the bean instance.
			//调用父类的方法进行创建这个标注了@Bean注解的bean
			return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
		}
	    //5.从容器中拿bean实例
		return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
	}

	private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
			ConfigurableBeanFactory beanFactory, String beanName) {

		// The user (i.e. not the factory) is requesting this bean through a call to
		// the bean method, direct or indirect. The bean may have already been marked
		// as 'in creation' in certain autowiring scenarios; if so, temporarily set
		// the in-creation status to false in order to avoid an exception.
		//6. 判断它是否正在创建
		boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
		try {
			if (alreadyInCreation) {
				beanFactory.setCurrentlyInCreation(beanName, false);
			}
			boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
			if (useArgs && beanFactory.isSingleton(beanName)) {
				// Stubbed null arguments just for reference purposes,
				// expecting them to be autowired for regular singleton references?
				// A safe assumption since @Bean singleton arguments cannot be optional...
				for (Object arg : beanMethodArgs) {
					if (arg == null) {
						useArgs = false;
						break;
					}
				}
			}
			//beanFactory.getBean
			//7. 这个方法就是从beanFactory容器中获取bean,beanFactory.getBean方法会去容器中进行查找bean,如果找不到则进行创建bean
			Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
					beanFactory.getBean(beanName));
			if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
				if (beanInstance.equals(null)) {
				
					beanInstance = null;
				}
				else {
				    //省略了这段代码,不重要
					throw new IllegalStateException();
				}
			}
			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);
			}
		}
	}
}

       在第三步是,需要判断FactoryBean类型,如果是的话就需要二次拦截,为什么?因为加了@Configuration如果在@Bean内部调用了其他@Bean注解的方法,Spring会进行拦截,然然后从容器中获取bean,如股票内部调用的bean是FactoryBean类型,而Spring不去拦截,那么就会根据方法名(此时不带“&”),获取的就是FactoryBean包裹的类型,这样就全错了,所以Spring会对FactoryBean类型进行拦截再判断,关于FactoryBean的使用想要了解更多的可以参考:Spring中FactoryBean的使用

       注意上面的方法不会在创建cglib代理的时候调用,只有在容器创建bean的时候调用,现在只是在动态的生成cglib代理对象。

       在第4步中,会判断当前拦截的这个Method方法是不是我们被我们标注了@Bean注解正要被创建的那个bean。说起来很拗口,也可以理解为使用了@bean注解的方法内部,你又去调用了其他标注了@bean注解的方法,这个当你调用其他标注了@bean注解的方法时,会先进行方法拦截器里面进行判断,如果不是,则会通过第5步去容器中通过getBean去获取对象。看一下代码块10.

代码块10:BeanMethodInterceptor#isCurrentlyInvokedFactoryMethod

private boolean isCurrentlyInvokedFactoryMethod(Method method) {
	//1.取出通过@Bean注解标注的方式标注的是哪个方法
	Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
	//2. 判断是否为同一个方法,方法名,参数类型和个数是否都一致
	return (currentlyInvoked != null && method.getName().equals(currentlyInvoked.getName()) &&
			Arrays.equals(method.getParameterTypes(), currentlyInvoked.getParameterTypes()));
}

        第1步会取出来我们在创建@bean注解的bean之前,标注的方法,所以我们来看一下SimpleInstantiationStrategy类是怎么进行标记的,看代码块11

代码块11:SimpleInstantiationStrategy类

public class SimpleInstantiationStrategy implements InstantiationStrategy {

	//ThreadLocal类型的,用来保存当前正在调用的工厂方法
	private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();

	//返回当前正在调用的工厂方法,如果没有,则返回{@code null}。
    //允许工厂方法实现确定当前调用方是否是容器本身,而不是用户代码
	@Nullable
	public static Method getCurrentlyInvokedFactoryMethod() {
		return currentlyInvokedFactoryMethod.get();
	}
	
	//用于设置当前正在调用的工厂方法
    @Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, final Method factoryMethod, @Nullable Object... args) {

		try {
		    //1. 安全检查
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					ReflectionUtils.makeAccessible(factoryMethod);
					return null;
				});
			}
			else {
				ReflectionUtils.makeAccessible(factoryMethod);
			}
			//2. 取出设置的工厂方法
			Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
			try {
			    //3. 将现在正在调用的工厂方法设置进去
				currentlyInvokedFactoryMethod.set(factoryMethod);
				//4. 然后调用正在工厂方法,其实就是在这一步调用的@Configuration类里面的@bean方法,来创建对象
				//而且在第3步可以看到是将currentlyInvokedFactoryMethod的值设置成正在调用的,用来标记它是容器进行调用的
				//方法,而非用户调用的代码,用户调用就是在@Bean方法内部你调用了其他@bean标注的方法,Spring会进行区分
				Object result = factoryMethod.invoke(factoryBean, args);
				if (result == null) {
					result = new NullBean();
				}
				return result;
			}
			finally {
			    //5. 将原来的给设置进行,因为之前的那个@bean还没有被创建完的
				if (priorInvokedFactoryMethod != null) {
					currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
				}
				else {
					currentlyInvokedFactoryMethod.remove();
				}
			}
		}
		catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
		}
	}
   
         //省略其他代码
}

     ThreadLocal是什么就不说了,大家如果想了解可以查看:深入理解ThreadLocal的原理及内存泄漏问题,这里面会详细的介绍ThreadLocal。

     看到这里可能有点蒙,没关系,使用一个例子进行描述:

@Configuration
@ComponentScan("com.luban.configuration")
public class Config {

	@Bean
	public School school() {
		School school = new School();
		school.setStudent(student());
		return school;
	}

	@Bean
	public Student student() {
		return new Student();
	}
}

       首先明白一点什么是容器调用的方法,什么是用户自己代码内部调用的方法:容器调用的方法指的就是在容器实例化Bean的时候,会自动调用调用加了@Bean的方法,将它变成一个Bean,就是Spring会在创建名称为school的Bean是,会调用school方法,这就是容器调用的,用户代码内部调用的方法,指的是在@Bean注解内部,你手动的调用了其他标注了@Bean的注解,就是你在school方法内部调用了student方法,这个方法就是用户自己调用的,Spring在进行处理@Configuration标注的类时是不同的。

      标注了@Bean注解的方法,也会变成一个beanDefinition,不过在beanDefinition内部是没有BeanClass的,只有FactoryMethod属性,指向它是使用哪个方法创建对象,在进行bean创建的时候,先判断FactoryMethod是否为空(如果是@Bean这样的类型就不为空),那么就会使用工厂方法创建对象,假设我们在创建名称为school的bean,那么先会执行代码块11的instantiate方法,将currentlyInvokedFactoryMethod置为school方法,进行标记school方法是容器调用的方法,然后就会进行方法拦截代码块9 BeanMethodInterceptor类的intercept方法,此时在其第4步的判断中isCurrentlyInvokedFactoryMethod(beanMethod)中为true,然后就会执行Config类的school方法,在执行到school.setStudent(student()),就会进入student()方法里面,在进行之前也会进入方法拦截器,此时又会执行代码块9 BeanMethodInterceptor类的intercept方法,此时在其第4步的判断中isCurrentlyInvokedFactoryMethod(beanMethod)中为false了,currentlyInvokedFactoryMethod是school方法,用于标记容器调用的方法为school方法,而我们在school内部调用了student方法,导致就不一样,所以为flase,然后就执行容器的getBean方法,去获取student的bean,发现没有就去创建,然后就会进行执行到代码块11的instantiate方法,先取出之前设置的,那就是school,并将currentlyInvokedFactoryMethod置为student方法,等到student的bean创建好后,又把currentlyInvokedFactoryMethod置为school方法。

  到这里关于@Configuration源码就看完了,更深层的细节我还没整懂,上面如果说的哪个地方有错误的可以指出来。

       另外,我们来可以来看一下使用cglib增强的类长什么样,可以帮助我们更好的理解cglib的原理:

       首先加上System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class")的代码,然后运行这个mian方法就可以了,然后就可以去C盘中查看cglib生成的类。

public class Test01 {
	public static void main(String[] args) {
		System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
	}
}

      这里我先贴出来没有增强之前的代码

@Configuration
@ComponentScan("com.luban.configuration")
public class Config {

	@Bean
	public School school() {
		return new School();
	}
}

       再贴出来增强后的代码: 

//继承了需要增强的Config类,并实现了EnhancedConfiguration接口
public class Config$$EnhancerBySpringCGLIB$$308299b4 extends Config implements ConfigurationClassEnhancer.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$school$0$Method;
  
  private static final MethodProxy CGLIB$school$0$Proxy;
  
  private static final Object[] CGLIB$emptyArgs;
  
  private static final Method CGLIB$setBeanFactory$5$Method;
  
  private static final MethodProxy CGLIB$setBeanFactory$5$Proxy;
  //正如我们所说的,会有一个BeanFactory类型,名称为$$beanFactory的属性
  public BeanFactory $$beanFactory;
  
  static void CGLIB$STATICHOOK1() {
    CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    CGLIB$emptyArgs = new Object[0];
    Class clazz1 = Class.forName("com.luban.configuration.Config$$EnhancerBySpringCGLIB$$308299b4");
    Class clazz2;
    CGLIB$setBeanFactory$5$Method = ReflectUtils.findMethods(new String[] { "setBeanFactory", "(Lorg/springframework/beans/factory/BeanFactory;)V" }, (clazz2 = Class.forName("org.springframework.beans.factory.BeanFactoryAware")).getDeclaredMethods())[0];
    CGLIB$setBeanFactory$5$Proxy = MethodProxy.create(clazz2, clazz1, "(Lorg/springframework/beans/factory/BeanFactory;)V", "setBeanFactory", "CGLIB$setBeanFactory$5");
    ReflectUtils.findMethods(new String[] { "setBeanFactory", "(Lorg/springframework/beans/factory/BeanFactory;)V" }, (clazz2 = Class.forName("org.springframework.beans.factory.BeanFactoryAware")).getDeclaredMethods());
    CGLIB$school$0$Method = ReflectUtils.findMethods(new String[] { "school", "()Lcom/luban/School;" }, (clazz2 = Class.forName("com.luban.configuration.Config")).getDeclaredMethods())[0];
    CGLIB$school$0$Proxy = MethodProxy.create(clazz2, clazz1, "()Lcom/luban/School;", "school", "CGLIB$school$0");
    ReflectUtils.findMethods(new String[] { "school", "()Lcom/luban/School;" }, (clazz2 = Class.forName("com.luban.configuration.Config")).getDeclaredMethods());
  }
  
  final School CGLIB$school$0() {
    return super.school();
  }
  //这个方法是被增强的方法
  public final School school() {
    if (this.CGLIB$CALLBACK_0 == null)
      CGLIB$BIND_CALLBACKS(this); 
	//进行方法的拦截
    return (this.CGLIB$CALLBACK_0 != null) ? 
	      (School)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$school$0$Method, CGLIB$emptyArgs, CGLIB$school$0$Proxy) : super.school();
  }
  
  final void CGLIB$setBeanFactory$5(BeanFactory paramBeanFactory) throws BeansException {
    super.setBeanFactory(paramBeanFactory);
  }
  
  public final void setBeanFactory(BeanFactory paramBeanFactory) throws BeansException {
    if (this.CGLIB$CALLBACK_1 == null)
      CGLIB$BIND_CALLBACKS(this); 
    if (this.CGLIB$CALLBACK_1 != null) {
      (new Object[1])[0] = paramBeanFactory;
      return;
    } 
    super.setBeanFactory(paramBeanFactory);
  }
  
  public Config$$EnhancerBySpringCGLIB$$308299b4() {
    CGLIB$BIND_CALLBACKS(this);
  }
  
  public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) {
    CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
  }
  
  public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) {
    CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
  }
  
  private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
    Config$$EnhancerBySpringCGLIB$$308299b4 config$$EnhancerBySpringCGLIB$$308299b4 = (Config$$EnhancerBySpringCGLIB$$308299b4)paramObject;
    if (!config$$EnhancerBySpringCGLIB$$308299b4.CGLIB$BOUND) {
      config$$EnhancerBySpringCGLIB$$308299b4.CGLIB$BOUND = true;
      if (CGLIB$THREAD_CALLBACKS.get() == null) {
        CGLIB$THREAD_CALLBACKS.get();
        if (CGLIB$STATIC_CALLBACKS == null)
          return; 
      } 
      config$$EnhancerBySpringCGLIB$$308299b4.CGLIB$CALLBACK_2 = (NoOp)((Callback[])CGLIB$THREAD_CALLBACKS.get())[2];
      config$$EnhancerBySpringCGLIB$$308299b4.CGLIB$CALLBACK_1 = (MethodInterceptor)((Callback[])CGLIB$THREAD_CALLBACKS.get())[1];
      config$$EnhancerBySpringCGLIB$$308299b4.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])CGLIB$THREAD_CALLBACKS.get())[0];
    } 
  }
  
  static {
    CGLIB$STATICHOOK2();
    CGLIB$STATICHOOK1();
  }
  
  static void CGLIB$STATICHOOK2() {}
}

      @Configuration总结:

        在Spring的生命周期中,其中会beanFactory的后置处理器,执行时,先执行beanFactory的子接口BeanDefinitionRegistryPostProcessor,在这一步完成会包的扫描和类上面注解信息的解析,然后将普通类转换成beanDefinition对象,其中标注了@Configuration注解的类,会在beanDefinition中标记为full。然后再执行BeanFactoryPostProcessor的postProcessBeanFactory方法,在这一步会对beanDefinition中标记为full的进行cglib代理增强,使用cglib代理增强就意味着需要增强类不能使用final关键字修饰,在这个cglib代理增强类中是间接的实现BeanFactoryAware接口,这样就可以拿到BeanFactory,并且会创建一个public、BeanFactory类型名称为$$beanFactory进行接收BeanFactory, 并且cglib代理类会对方法进行拦截,这样就不用了每次都去new一个对象,所以使用@Configuration可以保证bean的单一性,并且,如果标注了@Bean注解的方法返回的对象是FactoryBean类型的,Spring会进行二次拦截判断,确保是获取的bean是单一的。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值