Spring | 3.1.x 上
简介
x表示是3.1版本最后的一个版本,该版本发布于2013年1月。主要功能添加了注解配置beans,了解注解解析原理,是理解spring boot 实现的基础。该版本使用ant +ivy构建,
同时将单项目拆分为多项目开发。
Spring Framework 3.1 builds on the Spring Framework 3.0 foundation with a focus on Java-based application configuration and MVC enhancements.
回顾核心类图
IoC-Beans项目
XmlBeanFactory 被标记未过时的,功能迁移到Context 中去。
![](https://img.haomeiwen.com/i1228444/1c2535f19b2b20e8.png)
IoC-Context项目
1、新增AnnotationConfigApplicationContext
2、将AbstractRefreshableApplicationContext,AbstractXmlApplicationContext替换为GenericApplicationContext,因为支持了注解配置,AbstractXmlApplicationContext 不合适了。
![](https://img.haomeiwen.com/i1228444/0452ea06e8eacdb7.png)
注解配置实现
功能描述:获取class 的注解,解析成BeanDefinition并且注册。
核心类图
1、Bean定义
![](https://img.haomeiwen.com/i1228444/9a777da226d0117d.png)
2、注解元数据
![](https://img.haomeiwen.com/i1228444/079ce51c601d25ed.png)
核心实现代码
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
ClassPathBeanDefinitionScanner#scan 包扫描
ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider
ClassPathScanningCandidateComponentProvider#findCandidateComponents()
1、扫描包下面所有满足条件的class 文件
2、递归读取class上面的注解,使用了visitor pattern。
ClassReader reader =new ClassReader(Application.class.getName());
final AnnotationMetadataReadingVisitor visitor =new AnnotationMetadataReadingVisitor(Application.class.getClassLoader());
reader.accept(visitor, 2);
boolean filter = visitor.isAnnotated(Component.class.getName());
//解析后值保持在 :AnnotationAttributes (map) 中
![](https://img.haomeiwen.com/i1228444/b8723548fa8115e9.png)
3、依据filter 对class 文件进行排除和包含,includeFilters,excludeFilters
默认includeFilters,源码中filter里面只添加了一个@Component注解,但是我们配置的时候还有@Repository, @Controller ,@Service。也会被包含到includeFilters,就是由于注解的递归解析。
protected void registerDefaultFilters() {
// Component
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
//JSR-250
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));
// JSR-330
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));
}
4、将满足filter 条件的配置转换为BeanDefinition
小结
1、AOP 部分基本无变化,只扩展了几个默认的AbstractAutoProxyCreator。 AOP 部分之所以变化小,1、只依赖代理的实现技术,2、依赖bean 框架。依赖部分都是比较稳定。
2、IoC-beans 框架基本上也无变化,对bean的处理方式加强了一些功能。相反还去掉了一些功能,比如XmlBeanFactory
3、IOC-context 部分,核心部分也无变化,增加了一些扩展部分。精简了AbstractApplicationContext 的实现类层次。
4、注解的解析流程是Spring boot 项目的基础,注解的递归解析模型是Spring-Annotation-Programming-Model基础,注解解析使用访问者设计模式。