Spring IOC:ConfigurationClassPostProcessor解析(2)postProcessBeanFactory使用CGLIB增强配置类

引言

Spring IOC:ConfigurationClassPostProcessor解析提到对于配置类,不管是否使用了@Configuration都会进行注解的解析,那么@Configuration到底还有什么其他的作用呢?
Appconfig配置类

@Configuration
@ComponentScan("com.st")
public class Appconfig {
	@Bean
	public UserDao getUserDao(){
		return new UserDao();
	}

	@Bean
	public UserDao2 getUserDao2(){
		getUserDao();
		return new UserDao2();
	}
}

新建UserDao对象

package com.st.dao;

public class UserDao {
	public UserDao() {
		System.out.println("userDao1--init");
	}

	public void query(){}
}

新建UserDao2对象

package com.st.dao;

public class UserDao2 {
	public UserDao2() {
		System.out.println("UserDao2--init");
	}
	public void query(){}
}

package com.st.test;

import com.st.config.Appconfig;
import com.st.config.MyBeanFactoryPostProcessor;
import com.st.dao.Indexdao;
import com.st.dao.Indexdao2;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(Appconfig.class);
		//context.refresh();
		//context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
		context.refresh();
		//Indexdao2 indexdao = context.getBean(Indexdao2.class);
		//System.out.println(indexdao.getClass().getName());
	//	System.out.println(indexdao.hashCode()+"-------"+indexdao1.hashCode());
	}
}

当我们在配置类中使用了@Bean注解,在getUserDao2()中调用了getUserDao()
可以看到getUserDao()中创建了一个UserDao对象,而调用new UserDao()必然会执行对应的构造方法,所以在这里UserDao的无参构造会输出几次init呢?
执行结果:
在这里插入图片描述
说明了getUserDao()返回的是已经创建好的单例对象
现在把@Configuration去掉
执行结果:
在这里插入图片描述

@Configuration进行Cglib增强

在上一章节讲到了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,spring执行完这个方法之后还会执行这个类的postProcessBeanFactory方法。就是在这里对@Configuration进行了Cglib增强,使得getUser()时返回的是已产生的单例对象

@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);
		// postProcessorBeanFactory()方法也会调用processConfigBeanDefinitions方法,为了避免重复执行,
		// 所以在执行方法之前会先生成一个id,将id放入到一个set当中,每次执行之前
		// 先判断id是否存在,所以在此处,不会进入到if语句中
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
		//对@Configuration进行Cglib增强
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

进入enhanceConfigurationClasses(beanFactory)正式对@Configuration进行Cglib增强

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
			//拿到全注解的配置类
			//return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
				//省略。。。
			}
		}
		if (configBeanDefs.isEmpty()) {
			// nothing to enhance -> return immediately
			return;
		}

		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);
			try {
				// Set enhanced subclass of the user-specified bean class
				Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
				if (configClass != null) {
				   //调用ConfigurationClassEnhancer.enhance()方法创建增强类
					Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
					if (configClass != enhancedClass) {
						if (logger.isDebugEnabled()) {
							logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
									"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
						}
						beanDef.setBeanClass(enhancedClass);
					}
				}
			}
			catch (Throwable ex) {
				throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
			}
		}
	}

调用ConfigurationClassEnhancer.enhance()方法创建增强类,重点关注newEnhancer(configClass, classLoader)

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
			//省略。。。
		}
		//重点关注newEnhancer(configClass, classLoader)
		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
		if (logger.isDebugEnabled()) {
			logger.debug(String.format("Successfully enhanced %s; enhanced class name is: %s",
					configClass.getName(), enhancedClass.getName()));
		}
		return enhancedClass;
	}

为appconfig创建cglib,这里的重点是为cglib对象加入了父类,因为cglib是基于继承实现的。还有就是加入了两个拦截器BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor,实现了config类的增强

/**
	 * Creates a new CGLIB {@link Enhancer} instance.
	 */
	private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
		Enhancer enhancer = new Enhancer();
		//增强父类,Cglib的代理是基于父类的
		enhancer.setSuperclass(configSuperClass);
		//增强接口,为什么要增强接口?便于判断,表示一个类被增强了
		//基于接口的EnhancedConfiguration的父接口BeanFactoryAware中的setBeanFactory方法
		//设置这个变量的值为当前Context中的beanFactory,这个cglib代理类就有了beanFactory,这样就可以通过beanFactory获取对象了
		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
		enhancer.setUseFactory(false);
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		/*BeanFactoryAwareGeneratorStrategy是一个生成策略
		主要是为了生成的Cglib类中设置属性添加成员变量$$beanFactory
		BeanFactoryAwareGeneratorStrategy#transform	declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
		*/
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
		//当前的CALLBACK_FILTER为ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
		//CALLBACKS 为 new Callback[] {
		//			new BeanMethodInterceptor(),//调用intercept方法实现拦截,对加了@Bean注解的方法进行增强
		//			new BeanFactoryAwareMethodInterceptor(),//调用intercept方法实现拦截,为代理对象的beanFactory属性进行增强
		//			NoOp.INSTANCE }
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	}

BeanMethodInterceptor#intercept方法

public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
					MethodProxy cglibMethodProxy) throws Throwable {
			//通过enhancedConfigInstance中cglib的成员遍历$$beanFactory获得beanFactory
			ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
			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;
				}
			}

			
			//首先检查当前bean是不是一个FactoryBean,如果是就创建一个代理子类调用getObject方法返回一个bean实例
			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);
				}
			}
			//判断执行的方法和调用的方法是不是同一个方法
			//当执行到@Bean方法内调用其他getUserObject方法这里的执行方法和调用方法就不是同一个了
			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.
				if (logger.isWarnEnabled() &&
						BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
					
				}
				//创建bean并返回
				return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
			}
			//返回已经创建好的bean实例
			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
		}

BeanFactoryAwareMethodInterceptor#intercept 为代理对象设置beanFactory属性

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
			Assert.state(field != null, "Unable to find generated BeanFactory field");
			field.set(obj, args[0]);

			// Does the actual (non-CGLIB) superclass implement BeanFactoryAware?
			// If so, call its setBeanFactory() method. If not, just exit.
			if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
				return proxy.invokeSuper(obj, args);
			}
			return null;
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值