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
postProcessBeforeInitialization
methods of BeanPostProcessors- initializingBean’s
afterPropertiesSet
- a custom
init-method
definition postProcessAfterInitialization
methods of BeanPostProcessors
On shutdown of a bean factory:
postProcessBeforeDestruction
methods ofDestructionAwareBeanPostProcessors
- DisposableBean’s
destroy
- a custom
destroy-method
definition
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
ResourceLoader
interface. - 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
ApplicationContext
refresh will createBeanFactory
BeanFactory
will 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