SpringIOC源码解析

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的逻辑还是比较复杂的,这里先梳理一下:

  1. 先处理通过API方式注册的BeanFactoryPostProcessor
    1. 是否是BeanDefinitionRegistryPostProcessor类型的,是的话,执行postProcessBeanDefinitionRegistry方法
    2. 否则执行加入到regularPostProcessors集合中,等到BeanDefinitionRegistryPostProcessor执行完成后再执行
  2. 获取通过扫描得到的所有的BeanDefinitionRegistryPostProcessor
    1. 先获取实现了PriorityOrdered接口的实例,排序执行
    2. 获取实现了Ordered接口的实例,排序执行
    3. 获取普通的实例,排序执行
  3. 所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry执行完成之后,执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory,再执行通过API注册BeanFactoryPostProcessor的postProcessBeanFactory
  4. 获取通过扫描得到的所有的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值