zoukankan      html  css  js  c++  java
  • spring 学习-bean创建-重要类介绍

    问题

    • 生成的bean在哪里?
    • bean 容器,那么到底容器指的是哪个类呢?在那里呢
    • bean 中像作用域是如何实现的

    概述

    建议学习spring bean 源码的步骤可以 :

    • 先看官方文档关于bean 的知识点
    • 写 Demo 进行测试
    • 抓住主要的抽象接口,知道接口作用在慢慢嚼实现的细节

    重要的类

    下面介绍的几个类先对它有个整体的印象,不然在后面的源码分析会看得很乱。

    BeanFactory 和 ApplicationContext 的关系

    简单来说就是 BeanFactory 关于创建,生成bean 的接口,而 Context (上下文)更加具体点,增加对于企业级的功能接口。

    The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:
    
    - Easier integration with Spring’s AOP features
    
    - Message resource handling (for use in internationalization)
    
    - Event publication
    
    - Application-layer specific contexts such as the WebApplicationContext for use in web applications.
    
    In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of Spring’s IoC container. 
    
    

    BeanFactory 是个接口,提供了高级管理配置的机制,而 ApplicationContext 这是它的子接口提供特定企业级功能的扩展, 它的常见子类有 : ClassPathXmlApplicationContext or FileSystemXmlApplicationContext 。

    1297993-20200430150802571-1481202711.png

    AnnotatedGenericBeanDefinition 1297993-20200430151701108-2090354936.png

    BeanDefinition

    这个类是定义 bean 相关的 一些属性的,包括 :

    1297993-20200430154237923-2038228992.png

    Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:
    
    - A package-qualified class name: typically, the actual implementation class of the bean being defined.
    
    - Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).
    
    - References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.
    
    - Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.
    
    

    BeanFactoryPostProcess 和 BeanPostProcessor

    这两个东西完全是两个不同的东西,

    BeanPostProcessor 作用对象是 marker interfaces 和 proxies

    Factory hook that allows for custom modification of new bean instances — for example, checking for marker interfaces or wrapping beans with proxies.
    Typically, post-processors that populate beans via marker interfaces or the like will implement postProcessBeforeInitialization, while post-processors that wrap beans with proxies will normally implement postProcessAfterInitialization.
    
    

    看接口方法就可以知道什么意思了

    public interface BeanPostProcessor {
    
    
    	@Nullable
    	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    	@Nullable
    	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    

    这里先放出一张图,知道一下 BeanPostProcessor 作用的位置

    1297993-20200521175459316-1381114326.jpg

    我们也看到了 BeanPostProcessor 的两个方法 : postProcessBeforeInitialization 和 postProcessAfterInitialization ,不要错误地认为 "Initialization" 这是“设置属性”的过程,此时,而是后面 afterPropertiesSet 方法 和 init-method 的过程才叫 "Initialization". 说到 afterPropertiesSet 这个回调方法,其实在dubbo 嵌入 spring 中有用到见 : https://www.cnblogs.com/Benjious/p/12691204.html


    而 BeanFactoryPostProcess 同样也是后置处理器,只是他是 BeanFactory 里的后置处理器,它的作用对象是 bean definitions ,举个例子 BeanFactoryPostProcessor 有个子类 ConfigurationClassPostProcessor 它用来处理注解 @Configuration 的类,后置处理器会对注解 @Configuration 的类进行解析,处理属性,然后配置 BeanDefinition ,最终形成对应的 BeanDefinition 。

    beanfactory 提供“钩子(hook)”允许对应用程序上下文的bean定义进行自定义修改,以适应上下文基础bean工厂的bean属性值。
    
    对于针对用户的自定义配置文件很有用,这些文件覆盖了在应用程序上下文中配置的Bean属性。 请参阅PropertyResourceConfigurer及其具体实现,以获取可解决此类配置需求的即用型解决方案。
    
    BeanFactoryPostProcessor可以与Bean定义进行交互并对其进行修改,但不能与Bean实例进行交互。 这样做可能会导致bean实例化过早,从而违反了容器并造成了意外的副作用。 如果需要与bean实例交互,请考虑实现BeanPostProcessor。
    
    注解原文 : 
    
    Factory hook that allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.
    
    Useful for custom config files targeted at system administrators that override bean properties configured in the application context. See PropertyResourceConfigurer and its concrete implementations for out-of-the-box solutions that address such configuration needs.
    
    A BeanFactoryPostProcessor may interact with and modify bean definitions, but never bean instances. Doing so may cause premature bean instantiation, violating the container and causing unintended side-effects. If bean instance interaction is required, consider implementing BeanPostProcessor instead.
    
    

    总结 :

    • BeanFactoryPostProcessor 作用 bean definitions
    • BeanPostProcessor 作用 bean 实例化过程中

    Context 类重要类介绍

    我们知道Spring 注入bean 到容器中的方式有两种 : XML方式和java注解方式 。 Context 上下文可以说就是Spring 统筹管理者,从继承关系上讲可以见下面

    BeanFactory --> ApplicationContext --> AbsApplicationContext --> GenericApplicationContext
    
    

    从名字上可以看出 Context 上下文这个对象越来越具体化,

    AbsApplicationContext

    该类作为 ApplicationContext 的直接实现类,该类是个抽象类,使用了模板设计模式,限定了具体的流程,具体的操作细节交由子类实现,例如里面的 refresh 方法。既然是 ApplicationContext 的直接实现所以自然承接着事件通知等 ApplicationContext 应该有的功能实现

    Abstract implementation of the ApplicationContext interface. Doesn't mandate the type of storage used for configuration; simply implements common context functionality. Uses the Template Method design pattern, requiring concrete subclasses to implement abstract methods.
    In contrast to a plain BeanFactory, an ApplicationContext is supposed to detect special beans defined in its internal bean factory: Therefore, this class automatically registers BeanFactoryPostProcessors, BeanPostProcessors, and ApplicationListeners which are defined as beans in the context.
    
    A MessageSource may also be supplied as a bean in the context, with the name "messageSource"; otherwise, message resolution is delegated to the parent context. Furthermore, a multicaster for application events can be supplied as an "applicationEventMulticaster" bean of type ApplicationEventMulticaster in the context; otherwise, a default multicaster of type SimpleApplicationEventMulticaster will be used.
    
    Implements resource loading by extending DefaultResourceLoader. Consequently treats non-URL resource paths as class path resources (supporting full class path resource names that include the package path, e.g. "mypackage/myresource.dat"), unless the getResourceByPath method is overridden in a subclass.
    
    
    public abstract class AbstractApplicationContext extends DefaultResourceLoader
    		implements ConfigurableApplicationContext {
    		
    
    	/** Parent context. */
    	@Nullable
    	private ApplicationContext parent;
    
    	/** Environment used by this context. */
    	@Nullable
    	private ConfigurableEnvironment environment;
    
    	// BeanFactoryPostProcessor 列表用于 refresh 方法 
    	/** BeanFactoryPostProcessors to apply on refresh. */
    	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
    
    	/** System time in milliseconds when this context started. */
    	private long startupDate;
    
    	/** Flag that indicates whether this context is currently active. */
    	private final AtomicBoolean active = new AtomicBoolean();
    
    	/** Flag that indicates whether this context has been closed already. */
    	private final AtomicBoolean closed = new AtomicBoolean();
    
    	/** Synchronization monitor for the "refresh" and "destroy". */
    	private final Object startupShutdownMonitor = new Object();
    
    	/** Reference to the JVM shutdown hook, if registered. */
    	@Nullable
    	private Thread shutdownHook;
    
    	/** ResourcePatternResolver used by this context. */
    	private ResourcePatternResolver resourcePatternResolver;
    
    	// 声明周期相关处理
    	/** LifecycleProcessor for managing the lifecycle of beans within this context. */
    	@Nullable
    	private LifecycleProcessor lifecycleProcessor;
    
    	// MessageSource 相关 
    	/** MessageSource we delegate our implementation of this interface to. */
    	@Nullable
    	private MessageSource messageSource;
    
    	//事件广播 
    	/** Helper class used in event publishing. */
    	@Nullable
    	private ApplicationEventMulticaster applicationEventMulticaster;
    
    	//监听器 
    	/** Statically specified listeners. */
    	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
    
    	
    }
    
    

    GenericApplicationContext

    通用 ApplicationContext 就对 ApplicationContext 更进一步的具体话了,它的上一层是抽象类,对一些逻辑进行抽象处理,交给子类实现,而 GenericApplicationContext 就是最终的实现者。

    Generic ApplicationContext implementation that holds a single internal DefaultListableBeanFactory instance and does not assume a specific bean definition format. Implements the BeanDefinitionRegistry interface in order to allow for applying any bean definition readers to it.
    
    

    GenericApplicationContext 中最重要是它持有了一个 BeanFactory 的字段 : DefaultListableBeanFactory ,也是 Spring 的默认 BeanFactory 实现 。

    DefaultListableBeanFactory

    DefaultListableBeanFactory 是个非常重要的类,是一线工作的员工。

    Spring's default implementation of the ConfigurableListableBeanFactory and BeanDefinitionRegistry interfaces: a full-fledged(fledged:羽翼已丰的,能够飞翔的鸟) bean factory based on bean definition metadata, extensible through post-processors.
    
    Typical usage is registering all bean definitions first (possibly read from a bean definition file), before accessing beans. Bean lookup by name is therefore an inexpensive operation in a local bean definition table, operating on pre-resolved bean definition metadata objects.
    
    Note that readers for specific bean definition formats are typically implemented separately rather than as bean factory subclasses: see for example PropertiesBeanDefinitionReader and org.springframework.beans.factory.xml.XmlBeanDefinitionReader.
    
    For an alternative implementation of the org.springframework.beans.factory.ListableBeanFactory interface, have a look at StaticListableBeanFactory, which manages existing bean instances rather than creating new ones based on bean definitions.
    
    
    	/** Map from dependency type to corresponding autowired value. */
    	private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
    
    	//名字和 BeanDefinition 的映射 
    	/** Map of bean definition objects, keyed by bean name. */
    	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    
    	//
    	/** Map of singleton and non-singleton bean names, keyed by dependency type. */
    	private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
    
    	/** Map of singleton-only bean names, keyed by dependency type. */
    	private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
    
    	/** List of bean definition names, in registration order. */
    	private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
    
    	/** List of names of manually registered singletons, in registration order. */
    	private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
    
    	/** Cached array of bean definition names in case of frozen configuration. */
    	@Nullable
    	private volatile String[] frozenBeanDefinitionNames;
     
    

    总结

    本文作为spring bean 源码的解读,先介绍了几个重要的类,让我们在后续的解读中可以明白各自的关系。

    参考资料

    • https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
  • 相关阅读:
    Caffe的solver参数介绍
    局部响应归一化(Local Response Normalization,LRN)
    caffe中的学习率的衰减机制
    Caffe常用层参数介绍
    ubuntu 终端无法启动:ImportError: cannot import name 'sysconfig' from 'distutils'
    Python集合模块collections
    Python中的random模块
    HTTP状态码
    云计算中的地域和可用区概念
    Dropout原理解析
  • 原文地址:https://www.cnblogs.com/Benjious/p/15077919.html
Copyright © 2011-2022 走看看