曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享

曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解

曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下

曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean definition的?

曹工说Spring Boot源码(5)-- 怎么从properties文件读取bean

曹工说Spring Boot源码(6)-- Spring怎么从xml文件里解析bean的

曹工说Spring Boot源码(7)-- Spring解析xml文件,到底从中得到了什么(上)

曹工说Spring Boot源码(8)-- Spring解析xml文件,到底从中得到了什么(util命名空间)

工程代码地址 思维导图地址

工程结构图:

曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

概要

先给大家看看spring支持的xml配置,我列了个表格如下:

namespace element
util   constant、property-path、list、set、map、properties  
context   property-placeholder、property-override、annotation-config、component-scan、load-time-weaver、spring-configured、mbean-export、mbean-server  
beans   import、bean、alias  
task   annotation-driven、scheduler、scheduled-tasks、executor  
cache   advice、annotation-driven  
aop   config、scoped-proxy、aspectj-autoproxy  

我题目的意思是,spring在解析每个不同的xml元素时,其实是有共性的。所有这些元素的解析器,都实现了BeanDefinitionParser。这个接口只有一个方法,作用就是解析元素时,根据元素的配置,来收集beanDefinition,正所谓:条条大道通罗马,各种xml配置元素,各种注解配置,就是那些大道,罗马是什么?

就是beanDefinition。

从第一篇到现在,已经第9篇了,我们还在讲bean definition,其实就是因为,只有深刻地理解了它,后面才能更方便地理解spring boot,理解configuration注解,理解enable,理解自动装配。

好了,切入本篇,本篇要讲解的xml元素是context命名空间里的。

context:property-placeholder 用法 <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 "> <context:property-placeholder location="classpath*:application.properties"/> <bean> <property value="${name}"/> </bean> </beans> @Data public class TestPropertiesVO { private String name; } #application.properties name: Phil

测试代码:

package org.springframework.contextnamespace; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.util.MyFastJson; import java.util.List; import java.util.Map; @Slf4j public class TestPropertyPlaceholder { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[]{"classpath:context-namespace-test-property-holder.xml"},false); context.refresh(); Map<String, Object> map = context.getDefaultListableBeanFactory().getAllSingletonObjectMap(); log.info("singletons:{}", JSONObject.toJSONString(map)); List<BeanDefinition> list = context.getBeanFactory().getBeanDefinitionList(); MyFastJson.printJsonStringForBeanDefinitionList(list); // 获取该bean,打印 Object bean = context.getBean(TestPropertiesVO.class); System.out.println("bean:" + bean); } }

输出如下:

bean:TestPropertiesVO(name=Phil)

如果我们修改xml:

<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 "> //注释之,看看会怎样 <!--<context:property-placeholder location="classpath*:application.properties"/>--> <bean> <property value="${name}"/> </bean> </beans>

输出如下:

bean:TestPropertiesVO(name=${name})

可以看到,这样子呢,就没法解析到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 "> <!--<context:property-placeholder location="classpath*:application.properties"/>--> // 这个配置方式,和上面那个,效果其实是一样的;上面那个,是对下边这种的封装 <bean> <property> <list> <value>classpath:application.properties</value> </list> </property> </bean> <bean> <property value="${name}"/> </bean> </beans> 元素解析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdssz.html