Spring5.0.x源码分析(二)
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在容器中已经不是单例的了
注释掉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()));
}
}
可以看到getBeanFactoryPostProcessors()
获取到的就是没有加注解的自定义处理器,如果我们使用的是加了注解的自定义处理器,即上面第一次的情况运行到此处的话,其结果如下,getBeanFactoryPostProcessors()
方法返回为空
在未加注释的情况下进入到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初始化的过程中去做一些事情
for循环执行完成之后
往下执行到
// 排序
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)
进入本类中下面的方法
进入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;
}
}
是否被这四个注解注释
我们这里单独看一下自己写的加了注释的AppConfig类
3.4postProcessBeanFactory(beanFactory)
3.4postProcessBeanFactory(beanFactory)
3.4postProcessBeanFactory(beanFactory)
3.4postProcessBeanFactory(beanFactory)
推荐阅读
-
Spring5.0.x源码分析(二)
-
idea2019.2最快捷编译spring5.0.x源码
-
记idea 安装 spring5.0.x源码
-
Spring5.0.X源码的下载及Idea编译(一)
-
java源码分析之--ArrayList javaGC编程
-
java源码分析之--ArrayList javaGC编程
-
java File删除文件夹完整版 博客分类: java源码分析 javajava.io.filejava删除文件夹垃圾回收
-
java File删除文件夹完整版 博客分类: java源码分析 javajava.io.filejava删除文件夹垃圾回收
-
(11)muduo_base库源码分析:原子性
-
面试官问:你分析过 Mybatis 源码吗?——我是这么答的