Spring容器初探

SpringFactory容器

factory相关接口关系

Spring容器初探_第1张图片
ApplicationContext.png

BeanFactory接口组织架构

factory接口 实现功能
BeanFactory 定义了基本IOC容器的规范,包含像getBean()这样的IOC容器的基本方法
HierarchicalBeanFactory 增加了getParentBeanFactory()的接口功能,使BeanFactory具备了双亲IOC接口的关联功能
ConfigurableBeanFactory 主要定义了对BeanFactory的配置功能,比如通过setParentBeanFactory()设置双亲IOC容器,通过addBeanPostProcessor()配置Bean后置处理器,等等。
AutowireCapableFactory 这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等
ListableBeanFactory 可以列出工厂可以生产的所有实例。当然,工厂并没有直接提供返回所有实例的方法
MessageSource 提供国际化的消息访问
ResourceLoader 资源加载的功能
ApplicationContext 核心接口
ApplicationEventPublisher 功能就是发布事件,也就是把某个事件告诉的所有与这个事件相关的监听器
ConfigurableApplicationContext 提供设置活动和默认配置文件以及操作底层属性源的工具
WebApplicationContext 提供了Web环境的支持
ThemeSource 主题资源

BeanFactory和ApplicationContext的区别

Spring容器初探_第2张图片
ClassPathXmlApplicationContext.png

BeanFactory是spring中比较原始的Factory,如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口是由BeanFactory接口派生而来,因而具有BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能:
1.MessageSource, 提供国际化的消息访问
2.资源访问,如URL和文件
3.事件传播
4.载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层

bean加载过程

指定配置信息

有三种途径来进行bean的配置:
1.xml文件的方式配置,由ClassPathXmlApplicationContext加载配置文件
2.基于注解
3.Config类加注解的方式

BeanFactory容器启动

bean的启动过程就是AbstractApplicationContext类中的refresh()方法的执行

// Prepare this context for refreshing
   prepareRefresh();
    // Tell the subclass to refresh the internal bean factory.
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    // Prepare the bean factory for use in this context.
    prepareBeanFactory(beanFactory);
    try {
        // Allows post-processing of the bean factory in context subclasses.
        postProcessBeanFactory(beanFactory);
        // Invoke factory processors registered as beans in the context.
        invokeBeanFactoryPostProcessors(beanFactory);
        // Register bean processors that intercept bean creation.
        registerBeanPostProcessors(beanFactory);
        // Initialize message source for this context.
        initMessageSource();
        // Initialize event multicaster for this context.
        initApplicationEventMulticaster();
        // Initialize other special beans in specific context subclasses.
        onRefresh();
        // Check for listener beans and register them.
        registerListeners();
        // Instantiate all remaining (non-lazy-init) singletons.
        finishBeanFactoryInitialization(beanFactory);
        // Last step: publish corresponding event.
        finishRefresh();
    }

BeanDefination加载注册

AbstractXmlApplicationContext.loadBeanDefinitions()方法将任务交给reader来读取,最终走到AbstractBeanDefinitionParser.parse()方法.

//将bdf包装成bdfh对象
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
//将holder放入到BeanDefinitionRegistry对象中
registerBeanDefinition(holder, parserContext.getRegistry());
-----
//最终将holder中的bdf放入到DefaultListableBeanFactory的map中
/** Map of bean definition objects, keyed by bean name. */
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);

到此bdf添加到DefaultListableBeanFactory类中的beanDefinitionMap中.

prepareBeanFactory准备

主要完成一下操作:
1.设置ClassLoader类加载器到BeanFactory
2.BeanFactory添加BeanPostProcess,在初始化之前给目标bean设置各种aware对应的实例
3.设置BeanFactory忽略掉特殊的依赖,例如bean依赖aware接口实现类在自动装配的时候直接忽略aware目标实现类,spring会通过特殊的方式处理这些依赖.
4.为特殊的几个bean赋值,例如bean依赖BeanFactory类,则直接将对应的类实例对象赋值.
至此已经完成了对一些特殊bean的处理.

初始化所有的 singleton beans

经过一系列的周折最后到达AbstractAutowireCapableBeanFactory创建bean:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException{
    
    //1.说明不是 FactoryBean,这里实例化 Bean
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    //
    //2.这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
    populateBean(beanName, mbd, instanceWrapper);
    //3.进行实例化
    exposedObject = initializeBean(beanName, exposedObject, mbd);

}

对于创建bean有多种策略,简单的策略则是利用java的反射功能

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

}
---
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    return BeanUtils.instantiateClass(constructorToUse);
}
---
public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
        
    ReflectionUtils.makeAccessible(ctor);
    return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
                    KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
    }
}

特殊的FactoryBean处理过程

FactoryBean是一个工厂Bean,可以生成某一个类型Bean实例,它最大的一个作用是:可以让我们自定义Bean的创建过程。BeanFactory是Spring容器中的一个基本类也是很重要的一个类,在BeanFactory中可以创建和管理Spring容器中的Bean,它对于Bean的创建有一个统一的流程.包含三个重要的特性:是否单例、Bean类型、Bean实例.

bean的生命周期

Spring容器初探_第3张图片
WechatIMG55073.jpeg

1、实例化一个Bean
2、按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,传递的参数就是Spring配置文件中Bean的id值
4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(BeanFactory),传递的是Spring工厂自身
5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文
6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法
BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术
7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法
9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

BeanFactoryPostProcessor与BeanPostProcessor区别

1.BeanFactoryPostProcessor
实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息.
2.BeanPostProcessor
可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑.
这里的初始化方法有两种:
1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法
spring中,有内置的一些BeanPostProcessor实现类:

  • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
  • org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入
  • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
  • org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入
  • org.springframework.context.support.ApplicationContextAwareProcessor:用来为bean注入ApplicationContext等容器对象

你可能感兴趣的:(Spring容器初探)