前面两篇文章,我们从mybatis-spring的插件包出发,探究如何将第三方框架集成到spring中,也知道了mybatis中使用了FactoryBean+ImportBeanDefifinitionRegistrar+@Import对mapper进行注入。
不过我们在前两篇文章中仍然遗留很多疑点,例如
1、ImportBeanDefifinitionRegistrar是在什么时机被调用的,怎么被回调的,为什么不能搭配@Compnent一起使用?
2、mybatis是如何扩展spring的扫描器的?(扫描自定义注解或某个包下的类),而spring本身又是如何扫描的?
3、FeactoryBean的工作原理是什么?
4、BeanFactoryPostProcess的工作原理?怎么回调的?回调时机?本身是如何注入到spring中的?其子类的原理和作用?可以获取修改beandefinition,为什么不能注册?为什么有List<BeanFactoryPostProcess>这个集合?
5、什么是但理财、BeanDefinitionMap、@import是如何工作的?
下面我们才算开始学习spring源码,我们可以带着这些疑问,从源码的角度去解释这些疑问。
-----------------------------------------------------------------------------------------
一、什么是spring容器?

上面是spring官方对容器的一个解释:
BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext是BeanFactory的子接口,该子接口补充了下面的功能:
1、更容易与Spring的AOP特性集成
2、消息资源处理(用于国际化)
3、事件发布
4、应用程序层特定的上下文,如web应用程序中使用的WebApplicationContext。
简而言之,BeanFactory提供了配置框架和基本功能,ApplicationContext添加了更多企业特定的功能。ApplicationContext是BeanFactory的一个完整超集。

我们可以简单的总结spring容器:容器由spring多个组件组成(如各种后置处理器、扩展接口),用于管理任何类型对象,并提供多种应用功能。其主要存在两个分支:BeanFactory、ApplicationContext(两者都可以叫做spring的容器,只是提供的功能不同)。BeanFactory相当于一个标配版容器(提供了基本的对对象的管理),而ApplicationContext是选配豪华版容器(不仅提供了父接口的功能,还提供了依赖注入、各种注解扫描、更简单的aop集成、事件发布、国际化等等)。
Integrated lifecycle management----------------
Automatic BeanPostProcessor registration---------@Autowried等依赖注入功能
Automatic BeanFactoryPostProcessor registration-----------------
Convenient MessageSource access (for internationalization)------国际化功能
Built-in ApplicationEvent publication mechanism---------事件发布功能
我们从三个方面来举例两者的不同:(以ApplicationContext比BeanFactory多出了依赖注入、各种注解扫描、事件发布这三个功能举例)
1、依赖注入功能
2、注解扫描功能
3、事件发布功能(springboot中大量使用事件发布功能进行扩展)
代码实例:
1)、SpringContainerBean
package com.spring.demo.container;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
 * 测试依赖注入、注解扫描、事件发布等功能
 * */
@Slf4j
@Component
public class SpringContainerBean implements InitializingBean {
	//1、测试能否进行依赖注入
    @Autowired
    C c;
	@Autowired
	ApplicationContext context;
    public SpringContainerBean(){
		System.out.println("create SpringContainerBean  Object");
    }
	//2、测试能否扫描到这个注解
	//3、context.publishEvent()----测试事件发布功能
    @PostConstruct
    public void  init(){
		System.out.println("SpringContainerBean init PostConstruct");
		context.publishEvent(new ABeanInitEvent(context));
	}
    @Override
    public void afterPropertiesSet() throws Exception {
		System.out.println("SpringContainerBean init afterPropertiesSet");
    }
}
2)、依赖注入的类C
@Component
@Slf4j
public class C {
    public C(){
		System.out.println("create c Object");
    }
}3)、事件类
/**
 * 发布事件类不需要进行注入操作(监听的类需要进行注入操作)
 */
public class ABeanInitEvent extends ApplicationContextEvent {
	public ABeanInitEvent(ApplicationContext source) {
		super(source);
	}
}
4)、监听事件类
/**
 * 监听ABeanInitEvent事件(需要进行注入)
 * */
@Component
public class ABeanListener implements ApplicationListener<ABeanInitEvent> {
	@Override
	public void onApplicationEvent(ABeanInitEvent event) {
		System.out.println("event----" + event.getClass().getSimpleName());
	}
}5)、ApplicationContext容器的启动配置类ContextConfig
@Component
@ComponentScan("com.spring.demo.container")
public class ContextConfig {
}现在我们可以使用两个不同的容器,看看他们的功能区分:
启动ApplicationContext容器
public class ApplicationContextTest {
    public static void main(String[] args) {
        //获取ApplicationContext容器(传入ContextConfig配置类是为了让其自动调用register、refresh方法,也可以不传手动调用这两个方法)
		//这个ContextConfig就是我们平常写的Application类
        AnnotationConfigApplicationContext conext = new AnnotationConfigApplicationContext(ContextConfig.class);
	}
}查看打印结果:

启动BeanFactory容器
public class BeanFactoryTest {
    public static void main(String[] args) {
         DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SpringContainerBean.class);
		AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
		beanFactory.registerBeanDefinition("springContainerBean", beanDefinition);
		//BeanFactory注册的bean默认都是懒加载,需要手动getBean才会进行初始化
		beanFactory.getBean(SpringContainerBean.class);
	}
}
查看打印结果:

从上面的结果看到,BeanFatory容器确实不支持依赖注入(c构造方法没被打印),注解扫描(@
@PostConstruct注解方法没被执行),事件发布。但两者都支持对对象的基本管理(对对象进行注入,对实现了InitializingBean的方法调用)
那么BeanFatory既然本身没支持这些功能,我们可以自己给他扩展吗?
答案是可以的,例如我们以依赖注入功能为例,看看怎么实现:
我们先注释掉SpringContainerBean 的context代码
package com.spring.demo.container;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
 * 测试依赖注入、注解扫描、事件发布等功能
 * */
@Slf4j
@Component
public class SpringContainerBean implements InitializingBean {
	//1、测试能否进行依赖注入
    @Autowired
    C c;
	/*@Autowired
	ApplicationContext context;*/
    public SpringContainerBean(){
		System.out.println("create SpringContainerBean  Object");
    }
	//2、测试能否扫描到这个注解
	//3、context.publishEvent()----测试事件发布功能
   /* @PostConstruct
    public void  init(){
		System.out.println("SpringContainerBean init PostConstruct");
		context.publishEvent(new ABeanInitEvent(context));
	}*/
    @Override
    public void afterPropertiesSet() throws Exception {
		System.out.println("SpringContainerBean init afterPropertiesSet");
    }
}
修改BeanFactory代码:
public class BeanFactoryTest {
    public static void main(String[] args) {
         DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SpringContainerBean.class);
		//builder.getBeanDefinition().setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
		AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
		beanFactory.registerBeanDefinition("springContainerBean", beanDefinition);
		BeanDefinitionBuilder builderC = BeanDefinitionBuilder.genericBeanDefinition(C.class);
		AbstractBeanDefinition beanDefinitionC = builderC.getBeanDefinition();
		beanFactory.registerBeanDefinition("c", beanDefinitionC);
		//@Autowired的依赖注入原理就是依靠这个AutowiredAnnotationBeanPostProcessor,所以我们把他交给容器即可
		AutowiredAnnotationBeanPostProcessor auto = new AutowiredAnnotationBeanPostProcessor();
		auto.setBeanFactory(beanFactory);
		beanFactory.addBeanPostProcessor(auto);
		//BeanFactory注册的bean默认都是懒加载,需要手动getBean才会进行初始化
		//beanFactory.getBean(C.class);
		beanFactory.getBean(SpringContainerBean.class);
	}
}
如果知道@Autowrited注解的源码,应该就能知道@Autowired的依赖注入原理就是依靠这个AutowiredAnnotationBeanPostProcessor,所以我们需要把他交给容器。
这里还要注意一点:我们是没有去手动getBean(C.class)的,并且所以BeanFactory注入的bean都是懒加载的,如果我们依赖注入成功,则会打印C类的构造方法。
此时我们看下打印结果,发现依赖注入的功能实现了:

2、BeandefinitionMap?
前面说到一个对象被转化为一个BeanDefinition,然后基本会被put到BeandefinitionMap。而BeandefinitionMap存在两种BeanDefinition,一种spring自己内部的Beandefinition,一种我们通过spring的扩展注入的。
现在我们以ApplicationContex容器为例
1)、ApplicationContex容器中实例化了一个DefaultListableBeanFactory 从AnnotationConfigApplicationContext为入口: new AnnotationConfigApplicationContext ------------------》this()构造方法(有父类会先调用父类构造方法) ------------------》父类GenericApplicationContext的构造方法 -----------------》父类中存在一个属性DefaultListableBeanFactory beanFactory;并且构造方法会赋值this.beanFactory = new DefaultListableBeanFactory();
实际上就是以DefaultListableBeanFactory(BeanFactory容器为壳进行扩展自己的功能)为壳。
2)、进入DefaultListableBeanFactory
进入DefaultListableBeanFactory后我们可以发现一个属性------>
/** Map of singleton and non-singleton bean names, keyed by dependency type. */ Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); 其中key----bean的名字,values----某个类的Beandefinition对象
3)、开始断点查找扫描后BeanDefinition put进beanDefinitionMap的代码
经过不断debug,当我们执行完AnnotationConfigApplicationContext--->refresh();------>
invokeBeanFactoryPostProcessors()方法后beanDefinitionMap出现了我们自己注入的BeanDefinition对象
-----------------------invokeBeanFactoryPostProcessors()方法执行前

---------------------invokeBeanFactoryPostProcessors()方法执行后

所以我们可以推断 invokeBeanFactoryPostProcessors()方法完成了对我们自己注入的对象的扫描+put beanDefinitionMap的过程(执行这个方法之前Map没有值)
------------------------------invokeBeanFactoryPostProcessors方法执行前各个BeanDefinition的含义
(即此时未扫描我们自己注入的对象/类)
我们先不进去invokeBeanFactoryPostProcessors方法看其扫描的原理,我们先来看看这几个BeanDefinition的用处:
contextConfig -> 这是我们自己注册的BeanDefinition,因为实例化容器时需要传入这个类,所以就一同被注入了。
下面则是spring内部注册的Beandefinition:
1)、internalConfigurationAnnotationProcessor -> 对应的ConfigurationClassPostProcessor
该类是spring中非常重要的类,完成了spring的大部分工作(这里不细讲)
2)、internalEventListenerFactory" -> 对应的类DefaultEventListenerFactory
3)、internalEventListenerProcessor" -> 对应的类EventListenerMethodProcessor
4)、internalAutowiredAnnotationProcessor-> 对应类AutowiredAnnotationBeanPostProcessor
解析1@Autowrited注解依赖注入
5)、internalCommonAnnotationProcessor-> 对应的类CommonAnnotationBeanPostProcessor
解析@Resource注解依赖注入等功能,还有其他功能
这几个BeanDefinition是什么时候实例化出来的?
AnnotationConfigApplicationContext---》this()----->AnnotatedBeanDefinitionReader类的构造器
--->AnnotationConfigUtils类的registerAnnotationConfigProcessors()方法
	/**
	 * Register all relevant annotation post processors in the given registry.
	 * @param registry the registry to operate on
	 * @param source the configuration source element (already extracted)
	 * that this registration was triggered from. May be {@code null}.
	 * @return a Set of BeanDefinitionHolders, containing all bean definitions
	 * that have actually been registered by this call
	 */
	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//--------------------实例化BenDefinition
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//-------1、实例化出对应的BeanDefinition
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
//--------2、registerPostProcessor方法将其put到BeanDefinitionMap中
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}
		return beanDefs;
	}put到BeanDefinitionMap中是在registerPostProcessor方法中执行的,调用链:
registerPostProcessor() --->BeanDefinitionRegistry接口的registerBeanDefinition()方法 ----->其实现类DefaultListableBeanFactory中将BeanDefinition put到BeanDefinitionMap中
下篇我们开始讲invokeBeanFactoryPostProcessors()方法怎么扫描我们自己注入的对象/类,然后put到BeanDefinitionMap中的。


















