访问者模式在Spring源码中的应用
本节介绍访问者模式在 Spring 中的应用。
在 Spring IoC 中,BeanDefinition 用来存储 Spring Bean 的定义信息,比如属性值、构造方法参数或者更具体的实现。Spring 解析完配置后,会生成 BeanDefinition 并且记录下来。下次 getBean 获取 Bean 时,会通过 BeanDefinition 来实例化具体的 Bean 对象。
BeanDefinition 是一个接口,即一个抽象的定义,实际使用的是其实现类,如 ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition 等。
Spring 中的 BeanDefinitionVisitor 类主要用于访问 BeanDefinition,解析属性或者构造方法里面的占位符,并把解析结果更新到 BeanDefinition 中。这里应用的就是访问者模式。抽象元素为 BeanDefinition,具体元素有 RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition 等。
因为没有对访问者进行扩展,所以这里只有一个具体访问者 BeanDefinitionVisitor,没有再抽出一层抽象访问者。
BeanDefinitionVisitor 类的源码如下。
在 Spring IoC 中,BeanDefinition 用来存储 Spring Bean 的定义信息,比如属性值、构造方法参数或者更具体的实现。Spring 解析完配置后,会生成 BeanDefinition 并且记录下来。下次 getBean 获取 Bean 时,会通过 BeanDefinition 来实例化具体的 Bean 对象。
BeanDefinition 是一个接口,即一个抽象的定义,实际使用的是其实现类,如 ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition 等。
Spring 中的 BeanDefinitionVisitor 类主要用于访问 BeanDefinition,解析属性或者构造方法里面的占位符,并把解析结果更新到 BeanDefinition 中。这里应用的就是访问者模式。抽象元素为 BeanDefinition,具体元素有 RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition 等。
因为没有对访问者进行扩展,所以这里只有一个具体访问者 BeanDefinitionVisitor,没有再抽出一层抽象访问者。
BeanDefinitionVisitor 类的源码如下。
public class BeanDefinitionVisitor { @Nullable private StringValueResolver valueResolver; public BeanDefinitionVisitor(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); this.valueResolver = valueResolver; } protected BeanDefinitionVisitor() { } public void visitBeanDefinition(BeanDefinition beanDefinition) { visitParentName(beanDefinition); visitBeanClassName(beanDefinition); visitFactoryBeanName(beanDefinition); visitFactoryMethodName(beanDefinition); visitScope(beanDefinition); if (beanDefinition.hasPropertyValues()) { visitPropertyValues(beanDefinition.getPropertyValues()); } if (beanDefinition.hasConstructorArgumentValues()) { ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues(); visitIndexedArgumentValues(cas.getIndexedArgumentValues()); visitGenericArgumentValues(cas.getGenericArgumentValues()); } } protected void visitParentName(BeanDefinition beanDefinition) { String parentName = beanDefinition.getParentName(); if (parentName != null) { String resolvedName = resolveStringValue(parentName); if (!parentName.equals(resolvedName)) { beanDefinition.setParentName(resolvedName); } } } ... }以上没有使用双重分派模式,直接调用 visit 进行元素的访问。visitBeanDefinition() 方法分别实现了不同的 visit 来对相同的数据进行不同的处理。我们看到,在 visitBeanDefinition() 方法中,访问了其它数据,比如父类的名字、自己的类名、在 IoC 容器中的名称等各种信息。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算