Detailed explanation of the use and parsing of property placeholder in spring
When we develop applications based on spring, we usually put the database configuration in the properties file
Summary of knowledge points involved in code analysis:
1. The namespacehandler parses the custom namespace in the XML configuration file 2 Contextnamespacehandler is a context sensitive parser. Here, we define how to parse the property placeholder parser 3 Beandefinitionparser resolves the interface of bean deffinition 4 Bean factory postprocessor can modify the bean definition after loading it. 5 Propertysourcesplaceholderconfigurer handles placeholders in bean definition
Let's take a look at the specific use first
Use of property
Configure the properties file in the XML file
So / SRC / main / resources / foo The properties file will be loaded by spring
If you want to use multiple profiles, you can add an order field to sort
Configuration using propertysource annotation
Spring3. The @ propertysource annotation is added to facilitate adding property files to the environment
Injection and use of properties
1. Get by using @ value annotation in Java
You can also add a default value
1. Get in the XML configuration file of spring
Source code analysis
Loading of properties configuration information
When spring starts, it will start container initialization through abstractapplicationcontext#refresh, during which it will delegate loadeandefinitions to parse XML configuration files
Loadbeandefinitions find the defaultbeandefinitiondocumentreader #parsebeandefinition and resolve the specific bean through layer by layer delegation
Since this is not a standard class definition, it is delegated to beandefinitionparserdelegate for parsing
Find that the corresponding processor is contextnamespacehandler through namespacehandler, and then find propertyplaceholderbeandefinitionparser through ID for parsing
Propertyplaceholderbeandefinitionparser is the focus of this round of code analysis
Let's take a look at its parent class
1.BeanDeFinitionParser
Used by defaultbeandefinitiondocumentreader to parse personalized tags
Only one parse API for parsing elements is defined here
2.AbstractBeanDeFinitionParser
The default Abstract implementation of the beandefinitionparser interface Spring is good at providing many APIs that are convenient to use, and using the template method design pattern to provide custom implementation hooks for subclasses
Let's take a look at the specific processing logic of parse: the call hook parseinternal is parsed
3.AbstractSingleBeanDeFinitionParser
Resolve and define the abstract parent class of a single beandefinition
In parseinternal, resolve parentname, beanclass, source; And encapsulated with beandefinitionbuilder
4.AbstractPropertyLoadingBeanDeFinitionParser
Resolve property related properties, such as location, properties ref, file encoding, order, etc
5.PropertyPlaceholderBeanDeFinitionParser
There are not many things to deal with here, that is, setting ingore unresolved and system properties mode
Loading of properties file and instantiation of bean
Next, let's take a look at when this bean is instantiated. There are two kinds of instantiation of general classes. One is that a single instance is instantiated when the system starts; One is that non singleton (or singleton lazy loading) is instantiated at getBean
The trigger here is through beanfcatorypostprocessor
Beanfactoryprocessor modifies bean definition before bean instantiation. For example, placeholders in bean definition are solved here, and the properties we use now are also solved here
This is implemented through postprocessor registrationdelegate #invokebeanfactorypostprocessors Scan the beanfactoryprocessor in the container, find the required propertysourcesplaceholderconfigurer, and instantiate it through the getBean of the container
After the instantiation of propertysourcesplaceholderconfigurer is completed, it will be triggered directly and the information will be loaded
Let's take a look at the inheritance system of propertysourcesplaceholderconfigurer
1.beanfactoryPostProcessor
Define an interface for modifying the attribute of bean definition in the container Its implementation class is instantiated before the general class is used, and the properties of other classes are modified
This is obviously different from beanpostprocessor, which modifies bean instances
2.PropertiesLoaderSupport
Load the abstract class of the properties file
The specific loading logic here is to delegate the implementation of propertiesloaderutils#fillproperties
3.PropertyResourceConfigurer
The replacement of placeholders in bean definition is implemented by this abstract class
Implement beanfactorypostprocessor #postprocessbeanfactory, iterate the class definition in the container and modify it
How to modify it is implemented by subclasses through the hook processproperties
4.PlaceholderConfigurerSupport
Using the visitor design pattern, update properties through beandefinitionvisitor and stringvalueresolver
Stringvalueresolver is an interface for converting string type data. The API implementation for updating properties is actually in
PropertyPlaceholderHelper#parseStringValue
5.PropertySourcesPlaceholderConfigurer
Override the postprocessorbeanfactory API to define the parsing process
The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.