最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中property-placeholder的使用與解析詳解

 更新時間:2018年05月08日 15:30:56   作者:出門向左  
本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

我們在基于spring開發(fā)應(yīng)用的時候,一般都會將數(shù)據(jù)庫的配置放置在properties文件中.

代碼分析的時候,涉及的知識點概要:

1.NamespaceHandler 解析xml配置文件中的自定義命名空間
2.ContextNamespaceHandler 上下文相關(guān)的解析器,這邊定義了具體如何解析property-placeholder的解析器
3.BeanDefinitionParser 解析bean definition的接口
4.BeanFactoryPostProcessor 加載好bean definition后可以對其進行修改
5.PropertySourcesPlaceholderConfigurer 處理bean definition 中的占位符

我們先來看看具體的使用吧

property的使用

在xml文件中配置properties文件

<?xml version="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/beans
  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.2.xsd">

  <context:property-placeholder location="classpath:foo.properties" />
</beans>

這樣/src/main/resources/foo.properties文件就會被spring加載

如果想使用多個配置文件,可以添加order字段來進行排序

使用PropertySource注解配置

Spring3.1添加了@PropertySource注解,方便添加property文件到環(huán)境.

@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
 @Bean
 public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

properties的注入與使用

1.java中使用@Value注解獲取

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

還可以添加一個默認值

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

1.在Spring的xml配置文件中獲取

<bean id="dataSource">
 <property name="url" value="${jdbc.url}" />
</bean>

源碼解析

properties配置信息的加載

Spring在啟動時會通過AbstractApplicationContext#refresh啟動容器初始化工作,期間會委托l(wèi)oadBeanDefinitions解析xml配置文件.

 protected final void refreshBeanFactory() throws BeansException {
  if (hasBeanFactory()) {
   destroyBeans();
   closeBeanFactory();
  }
  try {
   DefaultListableBeanFactory beanFactory = createBeanFactory();
   beanFactory.setSerializationId(getId());
   customizeBeanFactory(beanFactory);
   loadBeanDefinitions(beanFactory);
   synchronized (this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
   }
  }
  catch (IOException ex) {
   throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
  }
 }

loadBeanDefinitions通過層層委托,找到DefaultBeanDefinitionDocumentReader#parseBeanDefinition解析具體的bean

 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.isDefaultNamespace(ele)) {
      parseDefaultElement(ele, delegate);
     }
     else {
      delegate.parseCustomElement(ele);
     }
    }
   }
  }
  else {
   delegate.parseCustomElement(root);
  }
 }

這邊由于不是標準類定義,所以委托BeanDefinitionParserDelegate解析

通過NamespaceHandler查找到對應(yīng)的處理器是ContextNamespaceHandler,再通過id找到PropertyPlaceholderBeanDefinitionParser解析器解析

 @Override
 public void init() {
  // 這就是我們要找的解析器
  registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
  registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
  registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
  registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
  registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
  registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
  registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
  registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
 }

PropertyPlaceholderBeanDefinitionParser是這一輪代碼分析的重點.

我們來看看它的父類吧.

1.BeanDefinitionParser

被DefaultBeanDefinitionDocumentReader用于解析個性化的標簽

這邊只定義了一個解析Element的parse api

public interface BeanDefinitionParser {
BeanDefinition parse(Element element, ParserContext parserContext);
}

2.AbstractBeanDefinitionParser

BeanDefinitionParser接口的默認抽象實現(xiàn).spring的拿手好戲,這邊提供了很多方便使用的api,并使用模板方法設(shè)計模式給子類提供自定義實現(xiàn)的鉤子

我們來看看parse時具體的處理邏輯把: 調(diào)用鉤子parseInternal解析

  1. 生成bean id,使用BeanNameGenerator生成,或者直接讀取id屬性
  2. 處理name 與別名aliases
  3. 往容器中注冊bean
  4. 進行事件觸發(fā)

3.AbstractSingleBeanDefinitionParser

解析,定義單個BeanDefinition的抽象父類

在parseInternal中,解析出parentName,beanClass,source;并使用BeanDefinitionBuilder進行封裝

4.AbstractPropertyLoadingBeanDefinitionParser

解析property相關(guān)的屬性,如location,properties-ref,file-encoding,order等

5.PropertyPlaceholderBeanDefinitionParser

這邊處理的事情不多,就是設(shè)置ingore-unresolvable和system-properties-mode

properties文件的加載,bean的實例化

接下來,我們再看看這個bean是在什么時候?qū)嵗?一般類的實例化有2種,一種是單例系統(tǒng)啟動就實例化;一種是非單例(或者單例懶加載)在getBean時實例化.

這邊的觸發(fā)卻是通過BeanFcatoryPostProcessor.

BeanFactoryPostProcessor是在bean實例化前,修改bean definition的,比如bean definition中的占位符就是這邊解決的,而我們現(xiàn)在使用的properties也是這邊解決的.

這個是通過PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors實現(xiàn)的.
掃描容器中的BeanFactoryPostProcessor,找到了這邊需要的PropertySourcesPlaceholderConfigurer,并通過容器的getBean實例化

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

PropertySourcesPlaceholderConfigurer實例化完成后,就直接進行觸發(fā),并加載信息

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

我們再來看看PropertySourcesPlaceholderConfigurer的繼承體系把

1.BeanFactoryPostProcessor

定義一個用于修改容器中bean definition的屬性的接口.其實現(xiàn)類在一般類使用前先實例化,并對其他類的屬性進行修改.

這跟BeanPostProcessor有明顯的區(qū)別,BeanPostProcessor是修改bean實例的.

2.PropertiesLoaderSupport

加載properties文件的抽象類.

這邊具體的加載邏輯是委托PropertiesLoaderUtils#fillProperties實現(xiàn)

3.PropertyResourceConfigurer

bean definition中占位符的替換就是這個抽象類實現(xiàn)的.

實現(xiàn)BeanFactoryPostProcessor#postProcessBeanFactory,迭代容器的中的類定義,進行修改

具體如何修改就通過鉤子processProperties交由子類實現(xiàn)

4.PlaceholderConfigurerSupport

使用visitor設(shè)計模式,通過BeanDefinitionVisitor和StringValueResolver更新屬性

StringValueResolver是一個轉(zhuǎn)化String類型數(shù)據(jù)的接口,真正更新屬性的api實現(xiàn)竟然是在

PropertyPlaceholderHelper#parseStringValue

5.PropertySourcesPlaceholderConfigurer

覆寫postProcessorBeanFactory api定義解析流程

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Springboot的高校社團管理系統(tǒng)的設(shè)計與實現(xiàn)

    基于Springboot的高校社團管理系統(tǒng)的設(shè)計與實現(xiàn)

    本文將基于Springboot+Mybatis開發(fā)實現(xiàn)一個高校社團管理系統(tǒng),系統(tǒng)包含三個角色:管理員、團長、會員。文中采用的技術(shù)有Springboot、Mybatis、Jquery、AjAX、JSP等,感興趣的可以了解一下
    2022-07-07
  • 基于SSM框架之個人相冊示例代碼

    基于SSM框架之個人相冊示例代碼

    本篇文章主要介紹了基于SSM框架之個人相冊示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Java8新特性之字符串去重介紹

    Java8新特性之字符串去重介紹

    這篇文章主要介紹了Java8新特性之字符串去重介紹,新的字符串去重特性可以幫助減少應(yīng)用中String對象的內(nèi)存占用,目前該特性只適用于G1垃圾收集器,并且默認不被開啟,需要的朋友可以參考下
    2014-09-09
  • mybatis-plus排除非表中字段的操作

    mybatis-plus排除非表中字段的操作

    這篇文章主要介紹了mybatis-plus排除非表中字段的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 一篇文章帶你入門Java字面量和常量

    一篇文章帶你入門Java字面量和常量

    這篇文章主要介紹了探究Java的常量,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • 帶你快速入門掌握Spring的那些注解使用

    帶你快速入門掌握Spring的那些注解使用

    注解是個好東西,注解是Java語法,被Java編譯器檢查,可以減少配置錯誤,這篇文章主要給大家介紹了關(guān)于Spring的那些注解使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • 親手帶你解決Debug Fastjson的安全漏洞

    親手帶你解決Debug Fastjson的安全漏洞

    這篇文章主要介紹了親手帶你解決Debug Fastjson的安全漏洞,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Spring Boot Web應(yīng)用開發(fā) CORS 跨域請求支持

    Spring Boot Web應(yīng)用開發(fā) CORS 跨域請求支持

    本篇文章主要介紹了Spring Boot Web應(yīng)用開發(fā) CORS 跨域請求支持,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳解java如何集成swagger組件

    詳解java如何集成swagger組件

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著java如何集成swagger組件展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • java字符串遍歷以及統(tǒng)計字符串中各類字符

    java字符串遍歷以及統(tǒng)計字符串中各類字符

    這篇文章主要為大家詳細介紹了java字符串遍歷以及字符串中各類字符統(tǒng)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評論

富裕县| 珠海市| 盱眙县| 工布江达县| 大石桥市| 安阳市| 高台县| 连江县| 彰化县| 九龙城区| 尚义县| 股票| 积石山| 台东县| 宣威市| 沙洋县| 启东市| 班玛县| 松潘县| 运城市| 河源市| 文成县| 泽库县| 蒙山县| 读书| 荣昌县| 女性| 公安县| 府谷县| 青州市| 景洪市| 齐齐哈尔市| 尼玛县| 江山市| 桐梓县| 松桃| 津市市| 兴义市| 宁夏| 德庆县| 伊宁县|