Spring basic concepts
BeanFactory is the root interface of the Spring Bean container. It defines the core method getBean(beanName) of the IoC container, and additionally provides methods such as continuesBean(beanName), isSingleton(beanName), etc. Its subinterfaces have other different purposes
interface AutowireCapableBeanFactory extends BeanFactory
Provides the ability to autowire. How to understand autowire?
interface HierarchicalBeanFactory extends BeanFactory
Hierarchical BeanFactory, provides the ability to obtain the ParentBeanFactory and check whether the current BeanFactory contains a bean (ignoring the bean of the same name in the ParentBeanFacotry)
The ability to set the BeanFactory hierarchy is provided by the setParentBeanFactory method of the subinterface ConfigurableBeanFactory of HierarchicalBeanFactory
interface ListableBeanFactory extends BeanFactory
Provides the ability to traverse and list all beans directly, instead of only getting them one by one through getBean
interface ConfigurableBeanFactory extends HierarchicalBeanFactory , SingletonBeanRegistry
Provides the ability to configure BeanFactory. For example, to set the hierarchical relationship
interface ConfigurableListableBeanFactory extends ListableBeanFactory , AutowireCapableBeanFactory , ConfigurableBeanFactory
Centralizes the capabilities of ListableBeanFactory and ConfigurableBeanFactory, and also provides the ability to analyze and modify BeanDefinition and pre-instantiate singleton beans
class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory , BeanDefinitionRegistry , Serializable
A mature BeanFactory based on BeanDefinition metadata, which can be extended by post-processors, register BeanDefinition, create and manage beans are all done by this class, this class is very important
ApplicationContext is to hold an instance of this class to delegate all BeanFactory and BeanDefinitionRegistry operations
interface BeanDefinition extends AttributeAccessor , BeanMetadataElement
BeanDefinition describes a Bean instance and provides the ability to set and obtain various properties of Bean. BeanFactory produces Beans according to BeanDefinition
interface BeanDefinitionRegistry extends AliasRegistry
Provides the ability to manage Beandefinition through beanName, including methods such as registration, removal, acquisition, and judging whether it exists
This is the only interface that encapsulates BeanDefinition in Spring's Bean Factory. The implementation of this interface includes DefaultListableBeanFactory and GenericApplicationContext
interface ApplicationContext extends EnvironmentCapable , ListableBeanFactory , HierarchicalBeanFactory , MessageSource , ApplicationEventPublisher , ResourcePatternResolver
It inherits the sub-interfaces ListableBeanFactory and HierarchicalBeanFactory of BeanFactory, provides the related capabilities of BeanFactory, and also provides the capabilities of environment assembly, resource processing, event publishing, internationalization, etc.
BeanFactory is responsible for Bean instantiation, assembly and acquisition. ApplicationContext contains all functions of BeanFactory, in addition to Bean life cycle management, post-processor (BeanFactoryPostProcessor/BeanPostProcessor) (supports extended functions, such as AOP) registration and invocation, Internationalization (accessing i18n-style messages through the MessageSource interface), accessing resources such as URLs and files through the ResourceLoader interface, event publishing mechanism, loading multi-level contexts through the HierarchicalBeanFactory interface, etc. Except for some specific scenarios (such as in the resource-constrained embedding device), should use ApplicationContext
The difference between a factory and a 4S shop
BeanFactory is the factory of Beans, the top-level core interface of spring. Without BeanFactory, there is no Bean. The factory is only responsible for producing Beans as required. The definition information of Beans is determined by the next home (ApplicationContext).
ApplicationContext is oriented to users, so it needs to better serve users, not only to provide beans and call factories to produce beans, but also to provide a series of user-friendly services (such as internationalization, loading bean definitions, listeners, etc...), how? Leave the Bean generation to the factory
But ApplicationContext also depends on the factory. Without the factory, he has no way to provide beans, and there is no way to better serve the user, so it needs to inherit the factory
// Note here that AnnotationConfigApplicationContext is also a BeanDefinitionRegistry class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
AnnotationConfigApplicationContext implements BeanDefinitionRegistry, and has the ability to register BeanDefinition. It also has a BeanFactory property, which is a DefaultListableBeanFactory, also implements BeanDefinitionRegistry, and also has the ability to register BeanDefinition. In fact, the ability to register BeanDefinitionRegistry of AnnotationConfigApplicationContext is delegated Implemented for DefaultListableBeanFactory
Used to explicitly register BeanDefinition programmatically. Is an alternative to ClassPathBeanDefinitionScanner. Responsible for registering configuration classes as BeanDefinitions
The main function of AnnotatedBeanDefinitionReader is to encapsulate and register some Genesis tool classes (roles are infrastructure components) as BeanDefinitions in the early stage of container startup, mainly including the following tool classes, and is also responsible for proxying the AnnotationConfigApplicationContext's ability to register BeanDefinitions
Used to scan all class files in a directory and its subdirectories to find candidate components (usually @Component annotations) that meet the conditions, and register them as BeanDefinition
The scanner instance created when the AnnotationConfigApplicationContext is initialized and the scanner instance used when parsing the configuration class during the SpringIoC container loading process are two different instances
When this class is in, it will call the registerDefaultFilters method, which will register includeFilters that filter candidate components during scanning. By default, the candidate components are required to contain any @Component, @ManagedBean, @Named, such as @Repository, @Service, @Controller. Annotations with classes that hold the @Component meta-annotation will also be scanned
Although classpath scanning is very fast, startup performance for large applications can be improved by creating a static list of candidates at compile time. In this mode, all modules of the application must use this mechanism, when the ApplicationContext detects such an index , it will automatically use it instead of scanning the classpath. The way to enable it is to introduce the spring-context-indexer dependency into the pom, this process will generate a file named META-INF/spring.components, which will be included in the jar package Medium. If META-INF/spring.components is found in the classpath, indexing will be automatically enabled. You can also configure whether to enable indexing by setting spring.index.ignore
The post-processor of BeanFactory shines in the first stage of IoC container loading (loading all configurations as BeanDefinition)
Its method postProcessBeanFactory passes in a BeanFactory. It works when all BeanDefinitions will be loaded, but no Beans have been instantiated. Can override or add properties, and can even be used to initialize Beans, usually to modify BeanDefinitions
interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
Its method postProcessBeanDefinitionRegistry passes in a BeanDefinitionRegistry. It works when all BeanDefinitions will be loaded, but no beans have been instantiated. BeanDefinition can be registered. Implementing this interface is equivalent to implementing BeanFactoryPostProcessor at the same time, so it will be used at the same time. Ability to modify and register BeanDefinitions
class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
The configuration class post-processor mainly finds the configuration class from all BeanDefinitions in the current stage, and then passes it to the ConfigurationClassParser to parse the configuration class, and registers all relevant candidate components as BeanDefinitions. Finally, add the configuration class annotated with @Configuration Do CGLib dynamic proxy
- Determine whether there is a ConfigurationClassPostProcessor.configurationClass property in the BeanDefinition, if it is, it means that it is a configuration class, which is added when the first judgment is made.
- If there is no ConfigurationClassPostProcessor.configurationClass property, you need to re-judge whether it is a configuration class. The following two conditions are met
- Annotated with @Configuration, marked as FULL configuration class
- There is no @Configuration annotation, but there is @Component, @ComponentScan, @Import, @ImportResource, or a method annotated with @Bean annotation in the class, marked as a LITE configuration class
The configuration class parser, parses the @PropertySource, @ComponentScan, @Import, @ImportSelector annotations on the configuration class and the methods annotated by the @Bean annotation in the configuration class. Register the parsed BeanDefinition in the container. If the parsed BeanDefinition is still a configuration class, then recursively parse
When parsing @ComponentScan, it will scan the specified basePackages path, and will be marked with @Component (@Repository, @Service, @Controller, @RestController, etc. contain @Component meta-annotations, and will also be scanned), @ManagedBean, @Named annotations The class also resolves to
Bean's post-processor, in the second stage of IoC container loading (producing all singleton configurations into beans) glows and heats up. During the creation process of each bean, various methods of BeanPostProcessor will be applied.
Provides two callback methods before and after Bean initialization. The Bean and BeanName are passed in. The default implementation is to return this Bean, which can be overridden and customized to implement either or both.
- postProcessBeforeInitialization: Executed before bean initialization
- postProcessAfterInitialization: Executed after bean initialization
Note that here is Initialization initialization, not Instantiation instantiation, these two are very similar, it is easy to confuse
There are 3 steps in the life cycle of a bean, 1. Instantiate, 2. Populate properties, 3. Initialize
interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor
Instantiate post processor, compared to BeanPostProcessor, added
- postProcessBeforeInstantiation: Executed before the bean is instantiated. Mainly to suppress the default instantiation of the target bean. If this method returns a non-null object, the bean creation process will be short-circuited. The only further processing on the bean is to call all BeanPostProcessors postProcessAfterInitialization method
- postProcessAfterInstantiation: Executed after the bean is instantiated and before the property is populated. If it returns false, the subsequent property population will be skipped, and other InstantiationAwareBeanPostProcessors will not act on the bean.
interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
Instantiate a post processor, compared to InstantiationAwareBeanPostProcessor, added
- predictBeanType: predicts the type of bean returned by the postProcessBeforeInstantiation callback
- determineCandidateConstructors: Determines candidate constructors to use for a given bean
- getEarlyBeanReference: Get the early Bean reference, the early one is the Bean before initialization after instantiation. Used to resolve circular dependencies
It is an interface implemented by the Bean class. If this interface is implemented, the Bean will no longer be an ordinary Bean (BeanName is &beanName), and it is responsible for creating a Bean (BeanName is beanName).
When traversing the beanName in the finishBeanFactoryInitialization method of refresh to create a singleton bean (get(beanName)), determine whether the class of the bean implements the ObjectBean interface. If so, the instantiation will not follow the default logic, but call the interface provided by the interface. getObject method to get the instance
BeanFactory is a Bean factory, FactoryBean is a special kind of Bean, this type of Bean is not instantiated by reflection, but by calling its getObject method and instantiated by itself programmatically
Although the name is very similar and easy to confuse, but completely 2 things
BeanFactory is the factory of beans, the top-level core interface of spring. Without BeanFactory, there is no Bean, and the importance can be imagined.
FactoryBean is also an interface, the bean modified by him will become a special bean, the original bean will be hidden, but the final bean will be returned by getObject of FactoryBean
Related: Spring basic concepts
- PropertyEditor Property Editor