Spring Core Container
本文介绍spring Core Container

Beans
Beans are created with the configuration metadata that you supply to the container.
In the container, the bean definitions are represented as BeanDefinition objects, contains:
- class
 - Name
 - Scope
 - Construct arguments
 - Properties
 - Autowiring mode
 - Initialization method
 - Destruction method
 
BeanDefinition
A BeanDefinition describes a bean instance, which has property values, constructor argument values.
This allow a BeanFactoryPostProcessor to introspect and modify property values and other bean metadata.
RootBeanDefinition represents the merged bean definition at runtime
interface BeanDefinition extends AttributeAccessor,BeanMetadataElement
interface AnnotatedBeanDefinition extends BeanDefinition {
    AnnotationMetadata getMetadata()
    MethodMetadata getFactoryMethodMetadata()
}
abstract class AbstractBeanDefinition implements BeanDefinition {
    Object beanClass
    String[] dependsOn
}
class GenericBeanDefinition extends AbstractBeanDefinition
class RootBeanDefinition extends AbstractBeanDefinition
BeanFactory
The root interface for accessing a spring bean container.
BeanFactory is a central registry of application components, and centralizes configuration components.
Bean Factory implementations should support the standard bean lifecycle interfaces as far as possible. The full ste of initialization methods and their standard order is:
- BeanNameAware’s 
setBeanName - BeanClassLoaderAware’s 
setBeanClassLoader - BeanFactoryAware’s 
setBeanFactory - EnvironmentAware’s 
setEnvironment - EmbeddedValueResolverAware’s 
setEmbeddedValueResolver - ResourceLoaderAware’s 
setResourceLoader - ApplicationEventPublisherAware’s 
setApplicationEventPublisher - MessageSourceAware’s 
setMessageSource - ApplicationContextAware’s 
setApplicationContext - ServletContextAware’s 
setServletContext postProcessBeforeInitializationmethods of BeanPostProcessors- initializingBean’s 
afterPropertiesSet - a custom 
init-methoddefinition postProcessAfterInitializationmethods of BeanPostProcessors
On shutdown of a bean factory:
postProcessBeforeDestructionmethods ofDestructionAwareBeanPostProcessors- DisposableBean’s 
destroy - a custom 
destroy-methoddefinition 
interface BeanFactory 
interface ListableBeanFactory extends BeanFactory
interface HierarchicalBeanFactory extends BeanFactory
interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
    void registerScope(String scopeName, Scope scope)
}
interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory
class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry
abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    Map<String, Scope> scopes
}
abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory
FactoryBean
Interface to be implemented by objects used within a BeanFactory which are themselves factories for individual objects.
A bean that implements this interface cannot be used as normal bean.
BeanFactoryPostProcessor
Factory hook that allows for custom modification of an application context’bean definitions.
An ApplicationContext auto-detects BeanFactoryPostProcessor beans in its bean definitions and applies them before any other beans get created.
ConfigurationClassPostProcessor A BeanFactoryPostProcessor used for bootstrapping processing of @Configuration class
interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
}
interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
}
class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
BeanPostProcessor
Factory hook that allows for custom modification of new bean instances
interface BeanPostProcessor {
+ Object postProcessBeforeInitialization(Object,String)
+ Object postProcessAfterInitialization(Object,String)
}
interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor  {
    void postProcessMergedBeanDefinition()
}
interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
    default boolean postProcessAfterInstantiation(Object bean, String beanName)
    default PropertyValues postProcessProperties()
}
interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor ,MergedBeanDefinitionPostProcessor
AutowiredAnnotationBeanPostProcessor
BeanPostProcessor implementation that autowires annotated fields,setter methods, and arbitrary config methods. Members to be injected are detected through annotations @Autowired and @Value
Scope
Strategy interface used by ConfigurableBeanFactory representing a target scope to hold bean instances in.
interface Scope {
    Object get(String name, ObjectFactory<?> objectFactory)
    Object remove(String name)
}
Core
SpringFactoriesLoader
SpringFactoriesLoader loads and instantiates factories of a given type from META-INF/spring.factories files which may be present in multiple JAR files
Environment
Environment Interface is an abstraction in container that models 2 key aspects of application environment.
A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active
Properties play an important role in almost all applications and may originate from a variety of sources: properties files, JVM system properties, system environment variables, JNDI, servlet context parameters, ad-hoc Properties objects, Map objects, and so on
title: Environment
skinparam linetype ortho
' Declare interfaces
interface PropertyResolver <<interface>> {
    boolean containsProperty(String key)
    String getProperty(String key)
}
interface ConfigurablePropertyResolver <<interface>>
interface Environment <<interface>>
interface ConfigurableEnvironment <<interface>>
interface ConfigurableWebEnvironment <<interface>>
' Declare classes
class AbstractEnvironment {
    Set<String> activeProfiles
    Set<String> defaultProfiles
    MutablePropertySources propertySources
    ConfigurablePropertyResolver propertyResolver
    protected void customizePropertySources(propertySources)
    protected ConfigurablePropertyResolver createPropertyResolver( propertySources)
}
class StandardEnvironment {
    protected void customizePropertySources(propertySources)
}
note "system properties system envs" as p1
StandardEnvironment .. p1
class StandardServletEnvironment {
    protected void customizePropertySources(propertySources)
}
package SpringBoot {
    class ApplicationServletEnvironment {
    }
}
' Define relationships with arrow pointing from class to interface (left to right)
PropertyResolver <|-- ConfigurablePropertyResolver
Environment <|-- ConfigurableEnvironment
PropertyResolver <|-- Environment
ConfigurablePropertyResolver<|-- ConfigurableEnvironment
ConfigurableEnvironment <|-- ConfigurableWebEnvironment
ConfigurableEnvironment <|-- AbstractEnvironment
AbstractEnvironment  <|-- StandardEnvironment
 StandardEnvironment  <-- StandardServletEnvironment
ConfigurableWebEnvironment  <|-- StandardServletEnvironment
StandardServletEnvironment <|-- ApplicationServletEnvironment        
properties
PropertySource Abstract base class representing a source of name/value property pairs. The underlying source object may be of any type T that encapsulates properties.
Examples include java.util.Properties objects,java.uti.Map objects,ServletContext and Sevletconfig objects.
@startuml
skinparam linetype ortho
interface Iterable<PropertySource> << interface >>
class MutablePropertySources {
    List<PropertySource<?>> propertySourceList
}
interface PropertySources << interface >> {
    
    Stream<PropertySource<?>> stream()
    PropertySource<?> get(String name)
}
abstract class PropertySource<T> {
    String name;
    T source
    abstract Object getProperty(String name)
    T getSource()
}
PropertySources          -|> Iterable    
MutablePropertySources  -|>  PropertySources        
MutablePropertySources o--      PropertySource      
@enduml
Context
ApplicationContext
ApplicationContext central interface to provide configuration for an application
- Bean factory methods for accessing application components. Inherited from 
ListableBeanFactory - The ability to load file resources. Inherited from 
ResourceLoaderinterface. - The ability to publish events to registered listeners. Inherited from the 
ApplicationEventPublisher 
@startuml
interface AnnotationConfigRegistry << interface >>
interface ApplicationContext << interface >>
interface ApplicationEventPublisher << interface >>
interface BeanDefinitionRegistry << interface >>
interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle
interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext
abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext
class DefaultResourceLoader implements ResourceLoader
interface EnvironmentCapable << interface >>
class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    DefaultListableBeanFactory beanFactory
}
class GenericWebApplicationContext extends GenericApplicationContext implements ConfigurableWebApplicationContext
interface Lifecycle << interface >>
interface ResourceLoader << interface >>
interface ResourcePatternResolver extends ResourceLoader
interface ApplicationContext extends EnvironmentCapable,MessageSource, ApplicationEventPublisher, ResourcePatternResolver
interface WebApplicationContext  extends ApplicationContext
class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
package SpringBoot {
    
    interface WebServerApplicationContext 
    interface ConfigurableWebServerApplicationContext extends  WebServerApplicationContext
    class ServletWebServerApplicationContext implements ConfigurableWebServerApplicationContext
    class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext 
}
  
ApplicationContext <|-------- WebServerApplicationContext
GenericWebApplicationContext <|-- ServletWebServerApplicationContext
ConfigurableApplicationContext <|-- ConfigurableWebServerApplicationContext
AnnotationConfigRegistry <|-- ServletWebServerApplicationContext
@enduml
Event
ApplicationListener can generically declare the event type that it is interested in. When registered with a Spring ApplicationContext, event will be filtered accordingly, with the listener getting invoked for matching event objects.
ApplicationListener can be defined in spring.factories, it can also be added by ClassPathBeanDefinitionScanner by invoking AbstractApplicationContext.registerListeners()
ApplicationEventMulticaster Interface to be implemented by objects that can manage a number of Applicationlistener objects and publish events to them.
SimpleApplicationEventMulticaster is the simple implementation of the ApplicationEventMulticaster interface.Multicasts all events to all registered listeners.
@startuml
!theme plain
top to bottom direction
skinparam linetype ortho
class ApplicationEvent {
   
}
interface ApplicationListener<E> << interface >> {
     void onApplicationEvent(E event)
}
interface EventListener << interface >>
interface ApplicationEventPublisher {
    void publishEvent(ApplicationEvent event) 
}
interface ApplicationEventMulticaster {
    void addApplicationListener(ApplicationListener<?> listener)
    void addApplicationListenerBean(String listenerBeanName)
    void multicastEvent(ApplicationEvent event)
}
ApplicationListener  -[#595959,dashed]->  ApplicationEvent    
ApplicationListener  -[#008200,plain]-^  EventListener     
ApplicationEventPublisher --> ApplicationEventMulticaster: publish
ApplicationEventMulticaster --> ApplicationListener: multicast
ApplicationEventPublisher <|-- ApplicationContext
@enduml
title: SimpleApplicationEventMulticaster
@startuml
!theme plain
top to bottom direction
skinparam linetype ortho
class AbstractApplicationEventMulticaster {
    ClassLoader beanClassLoader
    ConfigurableBeanFactory beanFactory
    DefaultListenerRetriever defaultRetriever
}
interface ApplicationEventMulticaster << interface >> {
    void multicastEvent(ApplicationEvent event)
}
interface Aware << interface >>
interface BeanClassLoaderAware << interface >> {
    void setBeanClassLoader(ClassLoader classLoader)
}
interface BeanFactoryAware << interface >> {
    void setBeanFactory(BeanFactory beanFactory)
}
class SimpleApplicationEventMulticaster {
    Executor taskExecutor
}
class DefaultListenerRetriever {
    Set<ApplicationListener<?>> applicationListeners
    Set<String> applicationListenerBeans
}
AbstractApplicationEventMulticaster *-left- DefaultListenerRetriever
AbstractApplicationEventMulticaster  -[#008200,dashed]-^  ApplicationEventMulticaster         
AbstractApplicationEventMulticaster  -[#008200,dashed]-^  BeanClassLoaderAware                
AbstractApplicationEventMulticaster  -[#008200,dashed]-^  BeanFactoryAware                    
BeanClassLoaderAware                 -[#008200,plain]-^  Aware                               
BeanFactoryAware                     -[#008200,plain]-^  Aware                               
SimpleApplicationEventMulticaster    -[#000082,plain]-^  AbstractApplicationEventMulticaster 
@enduml
Configuration
@Configuration annotation can be used to indicates that a class ’s primary purpose as a source of bean definitions,thus allow user to inject property sources, bean definitions in a much flexible way.
Spring uses ConfigurationClassPostProcessor to bootstrap Configuration class internally.
Annotation
@Configuration indicates that a class declares one more @Bean methods
@ComponentScan configures component scanning directives for use with @Configuration classes
@Import indicates one or more component classes to import
@ImportResource indicates oen or more resources containing bean definitions to import
@PropertySource provides a convenient and declarative mechanism for adding a PropertySource to Spring’s Environment. To be used in conjunction with @Configuration classes.
@Scope indicates the name of a scope to use
ConfigurationClassParser parses a Configuration class definition, populating a collection of ConfigurationClass objects.
Annotations processing sequence:
@PropertySource@ComponentScan@Import@ImportResource@Bean
ClassPathBeanDefinitionScanner detects bean candidates on the classpath, registering corresponding bean definitions with a given registry.
Candidates classes are detected through configurable type filters. The default filters include classes that are annotated with Spring’s
@Component@Repository@Service@Controller
ClassPathBeanDefinitionScanner is also responsible for creating Scoped Proxy for bean with @Scope annotation.
title component scan
class ConfigurationClassParser {
    BeanDefinitionRegistry registry
    ComponentScanAnnotationParser componentScanParser
    SourceClass doProcessConfigurationClass(configClass,sourceClass,filter)
}
class ConfigurationClassPostProcessor {
    void processConfigBeanDefinitions(BeanDefinitionRegistry registry)
}
class ComponentScanAnnotationParser {
    
}
class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    BeanDefinitionRegistry registry
    Set<BeanDefinitionHolder> doScan(String... basePackages)
}
ConfigurationClassPostProcessor --> ConfigurationClassParser: process
ConfigurationClassParser --> ComponentScanAnnotationParser: parse
ComponentScanAnnotationParser --> ClassPathBeanDefinitionScanner:scan
Application context initialization
ApplicationContextrefresh will createBeanFactoryBeanFactorywill load all beanDefinitions- BeanFactorypostprocess
- BeanDefinitionRegistryPostProcessor
- spring boot config bean
 - mybatis mapperscanner
 
 - BeanFactoryPostProcessor
- configClassEnhancer - proxy to generate bean
 
 
 - BeanDefinitionRegistryPostProcessor
 - init all Singleton Beans
 
title: Application context initialization
participant SpringApplication
group create 
SpringApplication -> DefaultApplicationContextFactory: createContext
activate DefaultApplicationContextFactory
DefaultApplicationContextFactory <- SpringFactoriesLoader: load ApplicationContextFactories
loop ApplicationContextFactories
DefaultApplicationContextFactory -> DefaultApplicationContextFactory: create
end
opt context is null
DefaultApplicationContextFactory -> DefaultApplicationContextFactory: create GenericApplicationContext
end
DefaultApplicationContextFactory -> SpringApplication: AnnotationConfigApplicationContext
end
deactivate DefaultApplicationContextFactory
title : bean factory initialization
AbstractApplicationContext--> AbstractApplicationContext:refresh
AbstractApplicationContext --> BeanFactory: create
BeanFactory --> BeanFactory:loadBeanDefinitions
AbstractApplicationContext --> AbstractApplicationContext:prepareBeanFactory
AbstractApplicationContext --> AbstractApplicationContext:postProcessBeanFactory
AbstractApplicationContext --> PostProcessorRegistrationDelegate:invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate --> BeanDefinitionRegistryPostProcessor:postProcessBeanDefinitionRegistry
AbstractApplicationContext--> AbstractApplicationContext:registerBeanPostProcessors
AbstractApplicationContext --> AbstractApplicationContext:finishBeanFactoryInitialization
AbstractApplicationContext --> BeanFactory:preInstantiateSingletons
bean Initialization
DefaultListableBeanFactory --> DefaultListableBeanFactory:preInstantiateSingletons
activate DefaultListableBeanFactory
DefaultListableBeanFactory --> DefaultListableBeanFactory:getMergedLocalBeanDefinition
DefaultListableBeanFactory --> DefaultListableBeanFactory:preInstantiateSingleton
activate DefaultListableBeanFactory
DefaultListableBeanFactory --> DefaultListableBeanFactory:instantiateSingleton
activate DefaultListableBeanFactory
DefaultListableBeanFactory --> DefaultListableBeanFactory:getBean
activate DefaultListableBeanFactory
DefaultListableBeanFactory --> DefaultListableBeanFactory: createBean
activate DefaultListableBeanFactory
DefaultListableBeanFactory --> DefaultListableBeanFactory: resolveBeanClass
alt proxy
DefaultListableBeanFactory --> DefaultListableBeanFactory: resolveBeforeInstantiation
note right: InstantiationAwareBeanPostProcessor
end
DefaultListableBeanFactory --> DefaultListableBeanFactory: createBeanInstance
activate DefaultListableBeanFactory
alt instanceSupplier
DefaultListableBeanFactory --> DefaultListableBeanFactory: obtainFromSupplier
end
DefaultListableBeanFactory --> BeanDefinition: getFactoryMethodName
alt factoryMethod
DefaultListableBeanFactory --> DefaultListableBeanFactory: instantiateUsingFactoryMethod
end
alt autowireNecesary
DefaultListableBeanFactory --> DefaultListableBeanFactory: autowireConstructor
else 
DefaultListableBeanFactory --> DefaultListableBeanFactory: instantiateBean
end
DefaultListableBeanFactory --> DefaultListableBeanFactory: determineConstructorsFromBeanPostProcessors
alt autowiremode
DefaultListableBeanFactory --> ConstructorResolver: new
ConstructorResolver --> ConstructorResolver: autowireConstructor
ConstructorResolver --> ConstructorResolver: instantiate
ConstructorResolver --> DefaultListableBeanFactory:beanWrapper
else 
DefaultListableBeanFactory --> DefaultListableBeanFactory:instantiateBean
end
deactivate 
DefaultListableBeanFactory --> DefaultListableBeanFactory:applyMergedBeanDefinitionPostProcessors
DefaultListableBeanFactory --> DefaultListableBeanFactory:populateBean 
note right: autowire Beans and handle properties
DefaultListableBeanFactory --> DefaultListableBeanFactory:initializeBean
DefaultListableBeanFactory --> DefaultListableBeanFactory: getSingleton
DefaultListableBeanFactory --> DefaultListableBeanFactory: registerDisposableBeanIfNecessary