The use and analysis of Property-placeholder in spring

Source: Internet
Author: User
Tags class definition

The use and analysis of Property-placeholder in spring

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 multiple profiles, 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.if (node instanceof Element) {Element ele = (element) node; if (Delegate.parsedefaultelement (Ele, delegate);} else {delegate.else {delegate. 

This way because it is not a standard class definition, so the delegate beandefinitionparserdelegate resolution through Namespacehandler to find the corresponding processor is Contextnamespacehandler, Find Propertyplaceholderbeandefinitionparser parser resolution by ID

    @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 was Defaultbeandefinitiondocumentreader used to parse the personalization label. This side 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 Parse, define the abstract parent class of a single beandefinition in Parseinternal, parse out parentname,beanclass,source; and use Beandefinitionbuilder for encapsulation

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

  5. Propertyplaceholderbeandefinitionparser here to deal with a few things, is to set 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. The substitution of placeholders in Propertyresourceconfigurer bean definition is implemented by this abstract class. Implementing Beanfactorypostprocessor#postprocessbeanfactory, iterating over the class definition in the container, making modifications specifically how to modify it through the hook processproperties to the subclass implementation

    4. Placeholderconfigurersupport using visitor design mode to update properties via 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

The use and analysis of Property-placeholder in spring

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.