Go The use and analysis of Property-placeholder in spring

Source: Internet
Author: User
Tags class definition

When we develop applications based on spring, we typically place the configuration of the database in the properties file.

At the time of code analysis, a summary of the knowledge points involved:

    1. Namespacehandler parsing a custom namespace in an XML configuration file
    2. Contextnamespacehandler a context-sensitive parser, which defines how to parse the Property-placeholder parser
    3. Beandefinitionparser interface for parsing bean definition
    4. Beanfactorypostprocessor The bean definition can be modified after loading it.
    5. Propertysourcesplaceholderconfigurer handling placeholders in bean definition

Let's take a look at the specific use.

Property usage Configure the properties file in the XML file
<?xmlVersion= "1.0" encoding= "UTF-8"?><Beans xmlns="Http://www.springframework.org/schema/beans" Xmlns:xsi="Http://www.w3.org/2001/XMLSchema-instance" xmlns:context="Http://www.springframework.org/schema/context" xsi:schemalocation="Http://www.springframework.org/schema/beansHttp://www.springframework.org/schema/beans/spring-beans-4.2.xsd http ://www.springframework.org/schema/context< Span class= "Hljs-tag" > http://www.springframework.org/schema/context/ Spring-context-4.2.xsd ">  <context:property-placeholder location= "classpath: Foo.properties " /></BEANS>          

So the/src/main/resources/foo.properties file will be loaded by spring
If you want to use more than one configuration file, you can add an order field to sort

Configuring with Propertysource annotations

Spring3.1 added @propertysource annotations to facilitate the addition of property files to the environment.

@Configuration@PropertySource("classpath:foo.properties")public class PropertiesWithJavaConfig {   @Bean   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {      return new PropertySourcesPlaceholderConfigurer();   }}
The injection and use of properties
    1. Use @value annotations in Java to get

      @Value( "${jdbc.url}" )private String jdbcUrl;

You can also add a default value

@Value( "${jdbc.url:aDefaultUrl}" )private String jdbcUrl;
    1. In the spring XML configuration file, get

      <bean id="dataSource">  <property name="url" value="${jdbc.url}" /></bean>
Source parsing properties configuration information loading

Spring starts the container initialization work through Abstractapplicationcontext#refresh at startup, and delegates the loadbeandefinitions parsing of the XML configuration file.

    Protected Final void Refreshbeanfactory()Throwsbeansexception {if (Hasbeanfactory ()) {Destroybeans ();Closebeanfactory (); }try {defaultlistablebeanfactory beanfactory =createbeanfactory (); beanfactory. setserializationid (getid ()); customizebeanfactory (beanfactory); loadbeandefinitions (beanfactory); synchronized (this.< Span class= "Fu" >beanfactorymonitor) {this.catch (IOException ex) {throw new  "I/O error parsing bean definition source for "+ getdisplayname (), ex);}           

Loadbeandefinitions to find Defaultbeandefinitiondocumentreader#parsebeandefinition parse specific bean through layer-by-layer delegation

    Protected void Parsebeandefinitions(Element root, Beandefinitionparserdelegate delegate) {if (delegate.isdefaultnamespace (Root)) {NodeList nl = root. getchildnodes (); for (int i = 0; I < NL. getlength (); i++) {Node node = nl. item (i); if (node instanceof Element) {Element ele = (element) node; if (Delegate.parsedefaultelement (Ele, delegate);} else {delegate.else {delegate. 

Because this is not a standard class definition, the delegate beandefinitionparserdelegate resolves
by Namespacehandler find the corresponding processor is Contextnamespacehandler, and then through the ID found Propertyplaceholderbeandefinitionparser parser parsing

    @OverridePublic void Init() {This is the parser we're looking for.Registerbeandefinitionparser ("Property-placeholder",NewPropertyplaceholderbeandefinitionparser ());Registerbeandefinitionparser ("Property-override",NewPropertyoverridebeandefinitionparser ());Registerbeandefinitionparser ("Annotation-config",NewAnnotationconfigbeandefinitionparser ());Registerbeandefinitionparser ("Component-scan",NewComponentscanbeandefinitionparser ());Registerbeandefinitionparser ( "Load-time-weaver", new Span class= "Fu" >loadtimeweaverbeandefinitionparser ()); registerbeandefinitionparser ( "spring-configured", span class= "kw" >new springconfiguredbeandefinitionparser ()); registerbeandefinitionparser ( "Mbean-export", new mbeanexportbeandefinitionparser ()); registerbeandefinitionparser ( "Mbean-server", new mbeanserverbeandefinitionparser ());}     

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 labels
    This only defines a parse API that parses element

    public interface BeanDefinitionParser {BeanDefinition parse(Element element, ParserContext parserContext);}
  2. Abstractbeandefinitionparser
    The default abstract implementation of the Beandefinitionparser interface. Spring's forte, this side provides a lot of handy API, and uses the template method design pattern to provide the child class with custom implementation hooks
    Let's take a look at parse when the specific handling logic puts:
    • Call Hook parseinternal Parsing
    • Generate Bean ID, generate using Beannamegenerator, or read ID attribute directly
    • Handling name and alias aliases
    • Registering beans in a container
    • To trigger an event
  3. Abstractsinglebeandefinitionparser
    Parsing, defining an abstract parent class for a single beandefinition
    In Parseinternal, the Parentname,beanclass,source is parsed and encapsulated using the Beandefinitionbuilder

  4. Abstractpropertyloadingbeandefinitionparser
    Parse Property-related properties, such as Location,properties-ref,file-encoding,order, etc.

  5. Propertyplaceholderbeandefinitionparser
    There's not much to deal with, it's setting up ingore-unresolvable and System-properties-mode.

Properties file loading, bean instantiation

Next, we look at when this bean is instantiated, there are 2 instances of the general class, one is the instantiation of a singleton system start-up, and a non-singleton (or singleton lazy loading) is instantiated at Getbean.
The trigger here is through beanfcatorypostprocessor.
Beanfactorypostprocessor is to modify the bean definition before the bean is instantiated, such as the placeholder in the bean definition is resolved here, and the properties we use now are resolved here.

This is achieved through postprocessorregistrationdelegate#invokebeanfactorypostprocessors.
Scan the beanfactorypostprocessor in the container, find the propertysourcesplaceholderconfigurer needed here, and instantiate it through the getbean of the container

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); }

Once the Propertysourcesplaceholderconfigurer instantiation is complete, it fires directly and loads the information

    OrderComparator.sort(priorityOrderedPostProcessors);    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

Let's take a look at the succession system of Propertysourcesplaceholderconfigurer

      1. Beanfactorypostprocessor
        Defines an interface that modifies the attributes of a bean definition in a container. Its implementation class is instantiated before the generic class is used, and the properties of other classes are modified.
        This is clearly different from Beanpostprocessor, where beanpostprocessor is modifying the bean instance.

      2. Propertiesloadersupport
        The abstract class that loads the properties file.
        Here the specific load logic is delegated propertiesloaderutils#fillproperties implementation

      3. Propertyresourceconfigurer
        The substitution of placeholders in bean definition is implemented by this abstract class.
        Implement Beanfactorypostprocessor#postprocessbeanfactory, iterate the class definition in the container, make modifications
        Specifically how to modify the hook processproperties by the sub-class implementation

      4. Placeholderconfigurersupport
        Use visitor design mode to update properties with Beandefinitionvisitor and Stringvalueresolver
        Stringvalueresolver is an interface that transforms string type data, and the API implementation that really updates the properties is Propertyplaceholderhelper#parsestringvalue

      5. Propertysourcesplaceholderconfigurer
        Overwrite Postprocessorbeanfactory API definition parsing process

Go The use and analysis of Property-placeholder in spring

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.