placeholder的使用与解析

我们在基于spring开发应用的时候,一般都会将数据库的配置放置在properties文件中.
代码分析的时候,涉及的知识点概要:

NamespaceHandler 解析xml配置文件中的自定义命名空间

ContextNamespaceHandler 上下文相关的解析器,这边定义了具体如何解析property-placeholder的解析器

BeanDefinitionParser 解析bean definition的接口

BeanFactoryPostProcessor 加载好bean definition后可以对其进行修改

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=" "> <context:property-placeholder location="classpath:foo.properties"/> </beans>

这样/src/main/resources/foo.properties文件就会被spring加载
如果想使用多个配置文件,可以添加order字段来进行排序

使用PropertySource注解配置

Spring3.1添加了@PropertySource注解,方便添加property文件到环境.

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

properties的注入与使用

java中使用@Value注解获取

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

还可以添加一个默认值

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

在Spring的xml配置文件中获取

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

源码解析 properties配置信息的加载

Spring在启动时会通过AbstractApplicationContext#refresh启动容器初始化工作,期间会委托loadBeanDefinitions解析xml配置文件.

protectedfinalvoidrefreshBeanFactory() 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

protectedvoidparseBeanDefinitions(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); } }

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

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