欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring5.0.x源码分析(二)

程序员文章站 2024-03-19 11:37:58
...

3、refresh()

继续看org.springframework.context.support.AbstractApplicationContext#refresh方法

3.4 postProcessBeanFactory(beanFactory)

是个空方法

3.5 invokeBeanFactoryPostProcessors(beanFactory)

Invoke factory processors registered as beans in the context,执行bean工厂后置处理器
下面做简单的测试

//定义个类,通过加注解,然后被扫描到加入到容器中,默认为单例
@Repository
public class UserDao {
}

定义MyBeanFactoryProcesser,拿到userDao这个bean在工厂中对应的BeanDefinition,通过BeanDefinition可以拿到关于userDao这个bean在Spring容器中的很多信息,这里我们将其设置为多例

@Component
public class MyBeanFactoryProcesser implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userDao");
		beanDefinition.setScope("prototype");
	}
}
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
		Object dao1 = ac.getBean("userDao");
		Object dao2 = ac.getBean("userDao");
		System.out.println(dao1);
		System.out.println(dao2);
	}
}

可以看到此时的UserDao在容器中已经不是单例的了
Spring5.0.x源码分析(二)
注释掉MyBeanFactoryProcesser@Component注解再次运行后,UserDao又是单例的了

修改测试方法如下

@Configuration
@ComponentScan("com.liaoxiang")
public class AppConfig {

}
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
		ac.register(AppConfig.class);
		ac.addBeanFactoryPostProcessor(new MyBeanFactoryProcesser());
		ac.refresh();
		Object dao1 = ac.getBean("userDao");
		Object dao2 = ac.getBean("userDao");
		System.out.println(dao1);
		System.out.println(dao2);
	}
}

此时UserDao又变成多例的了,加断点看一下,从3.5行所在代码直接进入invokeBeanFactoryPostProcessors()方法,定义在本类中

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 * =================================================================================================================!!
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//第二参数getBeanFactoryPostProcessors()获取的自定义的且没有加注解的bean工厂后置处理器
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

Spring5.0.x源码分析(二)
可以看到getBeanFactoryPostProcessors()获取到的就是没有加注解的自定义处理器,如果我们使用的是加了注解的自定义处理器,即上面第一次的情况运行到此处的话,其结果如下,getBeanFactoryPostProcessors()方法返回为空
Spring5.0.x源码分析(二)
在未加注释的情况下进入到PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()方法

final class PostProcessorRegistrationDelegate {

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
		//这里的beanFactory是DefaultListableBeanFactory对象,它实现了BeanDefinitionRegistry接口
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			//存放自定义的BeanFactoryPostProcessor--->MyBeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

			//BeanDefinitionRegistryPostProcessor已经继承了BeanFactoryPostProcessor接口
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//循环的是自定义的实现了BeanFactoryPostProcessor接口的类的集合,未加注解
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				/**
				 * 我们定义的处理器处理器实现的是BeanFactoryPostProcessor,所以这个为false
				 * 当我们定义的处理器实现的接口是BeanDefinitionRegistryPostProcessor时,就会进入这个方法
				 * 最后会将自定义的处理器加入到registryProcessors中
				 * BeanDefinitionRegistryPostProcessor接口扩展了BeanFactoryPostProcessor接口
				 * 扩展方法:
				 * 	postProcessBeanDefinitionRegistry
				 */
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				// 将自定义的处理器加入到regularPostProcessors
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// currentRegistryProcessors放的spring内部自己的实现了BeanDefinitionRegistryPostProcessor接口的处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 合并
			registryProcessors.addAll(currentRegistryProcessors);

			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
			.....
			//省略部分代码

两个Bean工厂后置处理器接口,这是spring的两个扩展点,实现这两个接口就可以插手beanFactory的创建过程(上一节中的BeanPostProcessor也是一个扩展点)

/**
 * Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 *
 * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
 * their bean definitions and apply them before any other beans get created.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context.
 *
 * <p>See PropertyResourceConfigurer and its concrete implementations
 * for out-of-the-box solutions that address such configuration needs.
 *
 * <p>A BeanFactoryPostProcessor may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * @author Juergen Hoeller
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
/**
 * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
 * the registration of further bean definitions <i>before</i> regular
 * BeanFactoryPostProcessor detection kicks in. In particular,
 * BeanDefinitionRegistryPostProcessor may register further bean definitions
 * which in turn define BeanFactoryPostProcessor instances.
 *
 * @author Juergen Hoeller
 * @since 3.0.1
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

将我们自定义(以后说自定义都是未加注解,自己显示new出来的)后置处理器加到名为regularPostProcessors的List集合中,(如果自定义的处理器加了注解交由Spring容器实例化,直接跳过for循环)此时for循环执行一次,然后往下执行到beanFactory.getBeanNamesForType()方法,跟进去,进入到DefaultListableBeanFactory类中,这个方法的作用是根据一个类型来拿到所有这个类型的类的类名,BeanDefinition中就描述的有类的类型和BeanName等,这里的这个方法就是在beanFactory中找出类型为BeanDefinitionRegistryPostProcessor.class的所有bean的beanName

// 参数为一个Class 和 两个布尔类型,上面传入的类型并不为null,if判断为true,调用doGetBeanNamesForType
@Override
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
		return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
	}
	Map<Class<?>, String[]> cache =
			(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
	String[] resolvedBeanNames = cache.get(type);
	if (resolvedBeanNames != null) {
		return resolvedBeanNames;
	}
	resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
	if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
		cache.put(type, resolvedBeanNames);
	}
	return resolvedBeanNames;
}

最后通过这个方法拿到了ConfigurationClassPostProcessor的BeanName,ConfigurationClassPostProcessor这个类是在上一节new AnnotatedBeanDefinitionReader(this)的时候加入到DefaultListableBeanFactory类中的beanDefinitionMap中的,为的就是在spring的beanFactory初始化的过程中去做一些事情
Spring5.0.x源码分析(二)
for循环执行完成之后
Spring5.0.x源码分析(二)往下执行到

// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并,如果我们自定义的处理器实现的是BeanDefinitionRegistryPostProcessor接口,就会加入到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

进入invokeBeanDefinitionRegistryPostProcessors(),还在本类中

/**
 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
 * ==================================================================================================================!!
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
		Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
	/**
	 * 循环所有的实现了BeanDefinitionRegistryPostProcessor接口的处理器
	 * 执行处理器中重写的postProcessBeanDefinitionRegistry()方法
	 */
	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

进入ConfigurationClassPostProcessor

/**
 * Derive further bean definitions from the configuration classes in the registry.
 */
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + registry);
	}
	this.registriesPostProcessed.add(registryId);

	processConfigBeanDefinitions(registry);
}

通过processConfigBeanDefinitions(registry)进入本类中下面的方法
Spring5.0.x源码分析(二)
Spring5.0.x源码分析(二)
进入checkConfigurationClassCandidate()

public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
	// 获取className
	String className = beanDef.getBeanClassName();
	if (className == null || beanDef.getFactoryMethodName() != null) {
		return false;
	}

	AnnotationMetadata metadata;
	/**
	 * 是AnnotatedBeanDefinition类型的实例
	 * 判断className和元数据里的className
	 */
	if (beanDef instanceof AnnotatedBeanDefinition &&
			className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
		// Can reuse the pre-parsed metadata from the given BeanDefinition...
		// 获得元数据
		metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
	}
	// 是AbstractBeanDefinition的实例
	else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
		// Check already loaded Class if present...
		// since we possibly can't even load the class file for this Class.
		Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
		metadata = new StandardAnnotationMetadata(beanClass, true);
	}
	// 不是上面的两种,从metadataReaderFactory中获取
	else {
		try {
			MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
			metadata = metadataReader.getAnnotationMetadata();
		}
		catch (IOException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
			}
			return false;
		}
	}
	// 是否加了注解@Configuration
	if (isFullConfigurationCandidate(metadata)) {
		// 如果加了就设置属性
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	else if (isLiteConfigurationCandidate(metadata)) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
	}
	else {
		return false;
	}

	// It's a full or lite configuration candidate... Let's determine the order value, if any.
	Integer order = getOrder(metadata);
	if (order != null) {
		//设置order
		beanDef.setAttribute(ORDER_ATTRIBUTE, order);
	}

	return true;
}

进入isLiteConfigurationCandidate(metadata)

public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
	// Do not consider an interface or an annotation...
	if (metadata.isInterface()) {
		return false;
	}

	// Any of the typical annotations found?
	for (String indicator : candidateIndicators) {
		if (metadata.isAnnotated(indicator)) {
			return true;
		}
	}

	// Finally, let's look for @Bean methods...
	try {
		return metadata.hasAnnotatedMethods(Bean.class.getName());
	}
	catch (Throwable ex) {
		if (logger.isDebugEnabled()) {
			logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
		}
		return false;
	}
}

是否被这四个注解注释
Spring5.0.x源码分析(二)
我们这里单独看一下自己写的加了注释的AppConfig类
Spring5.0.x源码分析(二)
Spring5.0.x源码分析(二)



3.4postProcessBeanFactory(beanFactory)

3.4postProcessBeanFactory(beanFactory)

3.4postProcessBeanFactory(beanFactory)

3.4postProcessBeanFactory(beanFactory)