Spring IOC原理解析
什么是IOC?IOC与DI是什么关系?
- IOC(Inversion of Control):即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
- DI(Dependency Injection):DI—Dependency Injection,即依赖注入:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的 klkkkmn,
- IOC和DI的关系:通俗来说就是IOC是设计思想,DI是实现方式。依赖注入明确描述了被注入对象依赖IoC容器的配置对象
IOC配置的三种方式
xml 配置
- 优点: 可以使用于任何场景,结构清晰,通俗易懂
- 缺点: 配置繁琐,不易维护,枯燥无味,扩展性差
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd>
<bean id="userService" class="com.handerh.spring.test.aop.db.jdbc.UserServiceImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
Java Config
将类的创建交给我们配置的JavcConfig类来完成,Spring只负责维护和管理,采用纯Java代码创建方式。其本质上就是把在XML上的配置声明转移到Java配置类中
- 优点:适用于任何场景,配置方便,因为是纯Java代码,扩展性高,十分灵活
- 缺点:由于是采用Java类的方式,声明不明显,如果大量配置,可读性比较差
@Configuration
public class AppConfig {
@Bean
public UserServiceImpl getUserServiceImpl(){
return new UserServiceImpl();
}
}
注解配置
通过在类上加注解的方式,来声明一个类交给Spring管理,Spring会自动扫描带有@Component,@Controller,@Service,@Repository这四个注解的类,然后帮我们创建并管理,前提是需要先配置Spring的注解扫描器。
- 优点:开发便捷,通俗易懂,方便维护。
- 缺点:具有局限性,对于一些第三方资源,无法添加注解。只能采用XML或JavaConfig的方式配置
@Configuration
@ComponentScan(value = "springframwork.config")
public class AppConfig {
}
DI依赖注入方式
构造方法
- java代码
@Autowired
public UserServiceImpl(DataSource dataSource){
jdbcTemplate = new JdbcTemplate(dataSource);
}
- xml配置
<bean id="userService" class="com.handerh.spring.test.aop.db.jdbc.UserServiceImpl">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
setter
- java代码
@Autowired
public void setDataSource(DataSource dataSource){
jdbcTemplate = new JdbcTemplate(dataSource);
}
- xml配置
<bean id="userService" class="com.handerh.spring.test.aop.db.jdbc.UserServiceImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
注解
@Service
public class UserServiceImpl {
@Autowired
private UserDaoImpl userDao;
}
IOC结构设计

- BeanFactory: 最顶层的一个接口类,IOC容器功能规范,它定义了IOC容器的基本功能规范,提供了操作Bean实例的基础方法
public interface BeanFactory {
// 区分普通bean实例与FactoyrBean的bean实例
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
}
- ListableBeanFactory:提供获取BeanDefinition的若干方法,如查看Bean 的个数,获取容器中所有的Bean的名称
public interface ListableBeanFactory extends BeanFactory {
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(@Nullable Class<?> type);
...
}
- HierarchicalBeanFactory: 父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器.Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean.
public interface HierarchicalBeanFactory extends BeanFactory {
BeanFactory getParentBeanFactory();
// Return whether the local bean factory contains a bean of the given name, ignoring beans defined in ancestor contexts.
boolean containsLocalBean(String name);
}
- AutowireCapableBeanFactory:定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
public interface AutowireCapableBeanFactory extends BeanFactory {
// 默认值,不进行自动注入,需要使用注解驱动
int AUTOWIRE_NO = 0;
// 根据set方法名称,自动注入
int AUTOWIRE_BY_NAME = 1;
// 根据set方法类型,自动注入
int AUTOWIRE_BY_TYPE = 2;
// 使用构造方法自动注入
int AUTOWIRE_CONSTRUCTOR = 3;
}
- ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了 ApplicationListener 事件监听接口的 Bean 可以接收到容器事件 , 并对事件进行响应处理 。 在 ApplicationContext 抽象实现类AbstractApplicationContext 中,我们可以发现存在一个 ApplicationEventMulticaster,它负责保存所有监听器,以便在容器产生上下文事件时通知这些事件监听者。
- ApplicationContext:IOC接口设计和实现,继承BeanFactory对Bean规范。包括更多的扩展功能,如事件发布机制,BeanFactoryPostProcessor对Bean容器的扩展等
ApplicationContext的实现
从整个类结构看,主要是围绕这两个接口GenericApplicationContext,AbstractRefreshableApplicationContext来扩展的
- GenericApplicationContext:初始化时构造容器,后续再次调用refresh方法不会更改
- AbstractRefreshableApplicationContext:每次refresh时都会清除原有的容器重新构造
在这两个类下面,衍生出ClassPathXmlApplicationContext,FileSystemXmlApplicationContext,AnnotationConfigApplicationContext等(还有spring web中以及springboot中的一些容器的实现)
- FileSystemXmlApplicationContext: 从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件。
- ClassPathXmlApplicationContext: 从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式。
- AnnotationConfigApplicationContext: 从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式。
GenericApplicationContext与AbstractRefreshableApplicationContext
关于这两个类的区别(调用refresh方法)在refreshBeanFactory这个方法中:
- GenericApplicationContext#refreshBeanFactory

- AbstractRefreshableApplicationContext

可以看到AbstractRefreshableApplicationContext类在执行refreshBeanFactory方法时会销毁之前的容器,然后重新创建一个。
接下来的原理分析都以AnnotationConfigApplicationContext类作为案例
容器的初始化
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.scan("com.handerh.spring.practice.base");
applicationContext.refresh();
先从构造函数开始分析
在上面的代码中,我创建了一个AnnotationConfigApplicationContext对象,在这个类的构造函数中初始化了两个对象,如下:
public AnnotationConfigApplicationContext() {
// 实例化AnnotatedBeanDefinitionReader对象,负责解析BeanDefinition
this.reader = new AnnotatedBeanDefinitionReader(this);
// 实例化包扫描器,负责扫描路径上的类
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
来看一下AnnotatedBeanDefinitionReader的构造函数:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
// 初始化BeanDefinition的注册器
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 这行代码很关键,会注册几个很关键的类的BeanDefinition到容器中
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils.registerAnnotationConfigProcessors
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//省略了 。。。
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4);
// 注册ConfigurationClassPostProcessor的BeanDefinition
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor的BeanDefinition
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));
}
// 注册CommonAnnotationBeanPostProcessor的BeanDefinition.
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));
}
//省略了 。。。
return beanDefs;
}
- ConfigurationClassPostProcessor:负责解析配置类,以及完成包扫描
- AutowiredAnnotationBeanPostProcessor:解析Autowired注解
- CommonAnnotationBeanPostProcessor:解析Rsource注解
这几个类很重要,到用到的地方再说
初始化包扫描器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// 注册一个扫描器的过滤器,只扫描加了@Component注解的类
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
scan扫描指定的包路径
- doScan方法
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 根据指定的包路径加载BeanDefinition
for (String basePackage : basePackages) {
// 加载BeanDefinition,根据初始化时包扫描器设置的过滤器进行过滤
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 生成bean的名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
// 为BeanDefinition添加一些默认的属性
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
// 如果类加了Lazy,Primary,DependsOn等注解,将其相关的属性给到BeanDefinition
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册BeanDefinition
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
到这里在指定包路径下的加了@Componet注解的类的BeanDefinition就已经加载到了容器中,但是容器的初始化还没有完成,还有很重要的逻辑在refresh方法中。
refresh
注意:refresh方法是在AbstractApplicationContext中的
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 在这个方法里面,记录容器已经开始启动以及容器的启动时间,初始化好Environment
prepareRefresh();
// 初始化好BeanFactory,这里也是之前提到的GenericApplicationContext与AbstractRefreshableApplicationContext的不同之处
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对BeanFactory添加扩展功能,比如SPEL表达式的支持,ApplicationContextAware的回调以及注册了一些与environment相关的bean
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// BeanFactoryPostProcessor以及BeanDefinitionRegistryPostProcessor的调用
invokeBeanFactoryPostProcessors(beanFactory);
// BeanPostProcessor的注册
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// 与事件发布机制有关
initApplicationEventMulticaster();
// 模版方法留给子类扩展
onRefresh();
// Check for listener beans and register them.
registerListeners();
// 实例化所有的Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
prepareRefresh
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// Initialize any placeholder property sources in the context environment
initPropertySources();
// 初始化Environment,将系统环境变量加入到Spring容器中
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 由子类实现,决定是否刷新spring容器, GenericApplicationContext与AbstractRefreshableApplicationContext的区别
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
invokeBeanFactoryPostProcessors
这个方法调用非常的重要,很多Spring的扩展功能都在这个方法的调用中体现,这里涉及到两个接口的调用:BeanFactoryPostProcessor以及BeanDefinitionRegistryPostProcessor
- BeanFactoryPostProcessor: 执行在 BeanFactory标准初始化之后,所有的Bean定义已经被加载,但Bean的实例还没被创建(不包括BeanFactoryPostProcessor类型)。该方法通常用于修改bean的定义,Bean的属性值等,甚至可以在此快速初始化Bean。
- BeanDefinitionRegistryPostProcessor:继承自BeanFactoryPostProcessor,新增了一个postProcessBeanDefinitionRegistry方法。执行在所有的Bean定义即将被加载,但Bean的实例还没被创建
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法执行时机的确先于BeanFactoryPostProcessor的postProcessBeanFactory方法。
Mybatis与Spring,Fegin与Spring的整合都是通过实现BeanDefinitionRegistryPostProcessor接口实现的,后面会展开解析。
invokeBeanFactoryPostProcessors的逻辑还是比较复杂的,这里先梳理一下:
- 先处理通过API方式注册的BeanFactoryPostProcessor
- 是否是BeanDefinitionRegistryPostProcessor类型的,是的话,执行postProcessBeanDefinitionRegistry方法
- 否则执行加入到regularPostProcessors集合中,等到BeanDefinitionRegistryPostProcessor执行完成后再执行
- 获取通过扫描得到的所有的BeanDefinitionRegistryPostProcessor
- 先获取实现了PriorityOrdered接口的实例,排序执行
- 获取实现了Ordered接口的实例,排序执行
- 获取普通的实例,排序执行
- 所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry执行完成之后,执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory,再执行通过API注册BeanFactoryPostProcessor的postProcessBeanFactory
- 获取通过扫描得到的所有的BeanFactoryPostProcessor,逻辑与【2】一致
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
// 1. 在这里没有去获取扫描到的BeanFactoryPostProcessor,而是自己通过API注册的,通过API注册的BeanFactoryPostProcessor先执行
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断是不是BeanDefinitionRegistryPostProcessor类型的,是的话执行postProcessBeanDefinitionRegistry方法
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 执行postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 加入到集合registryProcessors
registryProcessors.add(registryProcessor);
}
else {
// 说明是BeanFactoryPostProcessor类型的
regularPostProcessors.add(postProcessor);
}
}
// 用来存储当前要执行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 从BeanFactory中获取所有的BeanDefinitionRegistryPostProcessor实例
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 只取出带有PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 按照PriorityOrdered提供的顺序排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完成后清除currentRegistryProcessors,在下面执行还需要用上
currentRegistryProcessors.clear();
//处理实现了Ordered接口的,逻辑与PriorityOrdered处理逻辑一致
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 没有实现PriorityOrdered,Ordered接口的
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 执行BeanFactoryPostProcessor的后置处理方法,先执行BeanFactoryPostProcessor,再执行BeanFactoryPostProcessor的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取所有实现了BeanFactoryPostProcessor接口的bean
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 按照PriorityOrdered的顺序排序执行
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
在这里解释一下什么是通过API注册的,如下:
applicationContext.getBeanFactoryPostProcessors().add(new MyBeanFactoryPostProcessor());
applicationContext.getBeanFactoryPostProcessors().add(new MyBeanDefinitionResitryPostProcessor());
ConfigurationClassPostProcessor
在前面构造函数那个地方丢了三个BeanDefinition到容器中,如下
- ConfigurationClassPostProcessor:负责解析配置类
- AutowiredAnnotationBeanPostProcessor:解析Autowired注解
- CommonAnnotationBeanPostProcessor:解析Rsource注解
其中ConfigurationClassPostProcessor这个类实现了BeanDefinitionRegistryPostProcessor,负责加载BeanDefinition到容器中,这里贴一下大致的处理逻辑
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// Recursively process any member (nested) classes first
// 处理配置类中的内部类
processMemberClasses(configClass, sourceClass);
// 对配置类中 @PropertySource 注解解析处理
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 如果配置类上还加了ComponentScan,ComponentScans注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 继续扫描包路径下的类
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 对扫描到的BeanDefinition调用parse递归解析,如果是@Configuration注解,还会继续递归解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 解析@Import注解,解析ImportSelector,ImportBeanDefinitionRegistrar等引入的Bean实例
// 在springboot中就使用到了ImportSelector
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 解析带有 @Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 解析接口以及父类中的加了@Bean注解的方法
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
可以看到对于ConfigurationClassPostProcessor这个类会解析各种注解,将其引入的Bean的定义信息加载到Spring容器中
registerBeanPostProcessors
这个方法会注册所有BeanPostProcessor类型的Bean,在Bean实例化的时候进行前后置处理,会将
AutowiredAnnotationBeanPostProcessor以及CommonAnnotationBeanPostProcessor实例化一个单例Bean注册到容器中
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有BeanPostProcessor类型的bean
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
实例化Bean。。。
Bean实例化
在解析Bean实例化之前,先介绍一下在整个Bean实例化期间涉及到的一些扩展点/功能点
FactoryBean
@Component
public class MyFactoryBean implements FactoryBean {
private A a;
@Override
public Object getObject() throws Exception {
if (a != null){
return a;
}
a = new A();
return a;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
要获取实现FactoryBean的类实例,需要加上’&',否则获取到的是FactoryBean中getObject方法返回的实例
// com.handerh.spring.practice.facrotybean.A@77be656f
System.out.println(applicationContext.getBean("myFactoryBean"));
// com.handerh.spring.practice.facrotybean.MyFactoryBean@19dc67c2
System.out.println(applicationContext.getBean("&myFactoryBean"));
使用场景:Mybatis、Fegin与Spring整合的原理之一
BeanPostProcessor
BeanPostProcessor接口提供了两个方法,在所有Bean的实例化前后进行调用,可以对Bean做一些定制化的处理
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor(){
System.out.println("init MyBeanPostProcessor");
}
// bean实例化之前执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof A){
System.out.println(" postProcessBeforeInitialization MyBeanPostProcessor");
System.out.println(bean);
}
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
// bean实例化之后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof A){
System.out.println(" postProcessAfterInitialization MyBeanPostProcessor");
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
使用场景:之前在做蓝绿灰项目时,需要对DiscoverClient进行封装,使用到了BeanPostProcessor的后置处理方法:
PostConstruct注解
在Bean初始化时,回调加了注解@PostConstruct的方法,Bean的生命周期内回调一次
@Component
public class A {
public A(){
System.out.println("init Bean A");
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct...");
}
}
InitiallizeBean
功能与PostConstruct注解类似,也是在Bean初始化时回调指定的方法,不过InitiallizeBean是一个接口,使用在需要实现该接口:
@Component
public class A implements InitializingBean {
public A(){
System.out.println("init Bean A");
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet");
}
}
InitMethod
通过为Bean指定init-method以及destroy-method,来进行定制化Bean的初始化以及Bean的销毁流程,功能与PostConstruct以及InitiallizeBean类似,可在xml或者@Bean注解中指定
xxxAware
Spring提供了大量的xxxAware接口,这些接口在容器初始化时,都被忽略了自动注入的功能,因为实现了这些接口的类的Bean实例在整个Bean的生命周期都会被回调。
比如我们在开发中,用的最多的就是ApplicationContextAware。这个接口可以让我们在非Spring容器环境中,使用已经在Spring容器中已经初始化好的Bean,通常都是实现该接口,然后提供一堆静态方法。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.co.ayz.rpc.registry.ServiceRegistry;
public class ApplicationContextUtil implements ApplicationContextAware{
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
// TODO Auto-generated method stub
context = applicationContext;
}
//获得applicationContext
public static ApplicationContext getApplicationContext() {
//assertContextInjected();
return context;
}
public static void clearHolder(){
context=null;
}
//获取Bean
public static <T> T getBean(Class<T> requiredType){
//assertContextInjected();
return (T) getApplicationContext().getBean(requiredType);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name){
assertContextInjected();
return (T) getApplicationContext().getBean(name);
}
//判断application是否为空
public static void assertContextInjected(){
Validate.isTrue(context==null, "application未注入 ,请在springContext.xml中注入SpringHolder!");
}
}
bean的实例化
直接进到AbstractBeanFactory#doGetBean方法
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/**
* 转换对应的beanName
* 1. 别名转换 alias
* 2. FactoryBean 注册的factoryBean的实例都以&开头
*/
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 从缓存中加载单例bean singletonObjects
* 单例bean只会在容器中被创建一次,后续bean直接从缓存中获取
*/
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 如果是FactoryBean类型,会调用FactoryBean的getObject方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
BeanFactory parentBeanFactory = getParentBeanFactory();
/**
* 1.父类工厂存在
* 2.当前加载的XML配置文件中不包含该beanname
* 就到父类工厂去尝试加载该bean
*/
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 到父bean工厂加载
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 标记beanName已经被创建过至少一次 alreadyCreated
markBeanAsCreated(beanName);
}
//...删除了一些代码
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>(){
@Override
public Object getObject() throws BeansException {
// 实例化bean的核心逻辑
return createBean(beanName,mbd,args);
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
return (T) bean;
}
AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 使用构造函数进行Bean的初始化(这里面会有构造函数推断的逻辑,与自动注入模型有关)
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
/**
* 三级缓存,是否需要提早曝光
* 单例&&允许循环依赖&&当前bean正在创建中,检查循环依赖
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//bean实例化完成之前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean属性进行填充,将各个属性值注入,其中,可能存在依赖其它bean的属性,则会递归初始化
populateBean(beanName, mbd, instanceWrapper);
//调用bean的初始化方法 比如 init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// Register bean as disposable.
try {
//根据scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
// 获取bean定义中待注入的属性出 setXXX
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据配置的自动注入模型,找出另外需要填充的属性,放入到pvs中
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// AutowiredAnnotationBeanPostProcessor:解析Autowired注解
// CommonAnnotationBeanPostProcessor:解析Rsource注解
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// Autowired注解以及Resource注解属性注入
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 根据注入模型完成自动注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
initializeBean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 执行一些xxxAware的回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor的前置处理
// 这里会先执行@PostConstruct方法的回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 执行一些生命周期钩子函数
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor的后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Spring与Mybatis的整合
MapperScannerRegistrar
MapperFactoryBean
MapperScannerRegistrar

702

被折叠的 条评论
为什么被折叠?



