Spring源码系列文章
目录
一、Spring源码基础组件
- 阅读源码时候,接口与类过多,可以对照这里查看对应的关系
1、bean定义接口体系
2、bean工厂接口体系
3、ApplicationContext上下文体系
二、AnnotationConfigApplicationContext注解容器
配置类:
@ComponentScan("com.xc")
@Configuration
public class Config {
@Bean()
public Book book(){
return new Book();
}
}
启动类:
public class Client {
public static void main(String[] args) {
//创建注解容器,入参为配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
//获取某个bean
Book book = context.getBean(Book.class);
System.out.println(book);
//关闭容器
context.close();
}
}
AnnotationConfigApplicationContext的构造方法:
1、创建bean工厂-beanFactory
- 调用AnnotationConfigApplicationContext 的无参构造方法
- AnnotationConfigApplicationContext的父类是GenericApplicationContext
- 调用当前类的无参构造,先会
调用父类的无参构造
,先看下父类无参构造做的事情 - 这个beanFactory就是spring容器的核心实现类
- DefaultListableBeanFactory(bean容器)会存放
bean定义及bean名称集合等等
- DefaultListableBeanFactory父类DefaultSingletonBeanRegistry会缓存
所有实例化的bean
- 接下来继续查看AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner的创建
2、注册默认后置处理器
- 调用AnnotatedBeanDefinitionReader的有参构造方法
- 注册默认后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 1.获取之前创建好的DefaultListableBeanFactory对象,beanFactory实例
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// 2.为beanFactory添加两属性
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// 3.bean定义持有集合(持有bean定义、名字、别名)
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 查询beanDefinitionMap是否有 internalConfigurationAnnotationProcessor = ConfigurationClassPostProcessor
// 3.1.注册@Configuration,@Import,@ComponentScan,@Bean等注解 bean定义后置处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 注册到beanDefinitionMap中,并添加到beanDefs集合中
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor
// 3.2.注册@Autowired注解 bean后置处理器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// JSR-250,是java定义的一些注解,spring支持这注解。大致有:@PostConstruct @PreDestroy @Resource
// 3.3.注册@Resource @PostConstruct @PreDestroy注解 bean后置处理器
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 3.4.spring注册支持jpa注解的beanFactory后置处理器
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 3.5.注册事件监听后置处理器 EventListenerMethodProcessor
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 3.6.注册事件监听工厂 DefaultEventListenerFactory
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
- 查看一共注册的beanDefinition
- internalConfigurationAnnotationProcessor = ConfigurationClassPostProcessor
@Configuration,@Import,@ComponentScan,@Bean等注解 bean定义后置处理器
- internalAutowiredAnnotationProcessor = AutowiredAnnotationBeanPostProcessor
@Autowired注解 bean实例化后置处理器
- internalCommonAnnotationProcessor = CommonAnnotationBeanPostProcessor
@Resource @PostConstruct @PreDestroy注解 bean实例化后置处理器
- internalEventListenerProcessor = EventListenerMethodProcessor 事件监听后置处理器
- internalEventListenerFactory = DefaultEventListenerFactory 事件监听工厂
3、自定义扫描包功能
- 调用ClassPathBeanDefinitionScanner的有参构造方法
protected void registerDefaultFilters() {
// 注册过滤器 添加 @Component
// @Controller @Service @Repository 也会被扫描
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 扫描 JSR-250 @ManagedBean
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
//扫描 JSR-330 @Named
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
- 注册扫描过滤器 @Component,@Controller 、@Service、 @Repository 也会被添加进去
- ClassPathBeanDefinitionScanner类:主要为了扩展AnnotationConfigApplicationContext添加一个自助扫描包的功能
- 配置类上@ComponentScan注解扫描包路径下bean也是由此类实现
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
context.scan("com.xc.entity");
查看扫描包的源码
- 这个方法主要就是进行扫描包路径,然后得到一个beanDefinition集合
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 遍历扫描路径
for (String basePackage : basePackages) {
// 扫描得到beanDefinition,主要进行行excludeFilters、includeFilters判断和Conditional判断
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
// 遍历BeanDefinition
for (BeanDefinition candidate : candidates) {
// 解析scope注解信息
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
// 设置scope注解信息
candidate.setScope(scopeMetadata.getScopeName());
// 主要是解析Component有没有设置bean的名字,有则直接返回
// 没有则根据短名构造一个(如果写的名字第1、2个字符是大写则直接返回,否则直接将第一个字符转成小写返回)
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 主要是给BeanDefinition设置一些默认的值
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 获取类上的@Lazy、@Primary、@DependsOn、@Role、@Description相关信息并设置到定义信息中
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查Spring容器中是否已经存在该beanName,有的话会判断是否匹配,匹配则不会加入spring容器
// 不匹配则抛出异常,没有则直接加入spring容器
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
- 扫描bean的代码在findCandidateComponents中,进入
- addCandidateComponentsFromIndex方法就是读取META-INF目录下的缓存文件
- 解析原理和scanCandidateComponents一样
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
/**
* //解析是否有文件写的有component注解
* if()里面就是判断META-INF目录下面是否有写components文件
* (在该文件里面可以直接定义bean)然后在解析这个文件,其逻辑大致和下面一样
*/
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
} else {
return scanCandidateComponents(basePackage);
}
}
- 该方法主要是获得扫描路径下面的所有file对象(.class)
- 然后读取注解信息,判断与excludeFilters、includeFilters是否匹配以及Conditional条件判断
- 最后判断是否独立的非接口非抽象类的普通类,或者@Lookup注解的抽象类,最终返回BeanDefinition集合
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 获取basePackage下所有的文件资源
// classpath*:/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// classpath文件下的所有file对象
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
try {
// 元数据读取器,读取注解的信息,类的信息,接口抽象类,父类等
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 判断是不是一个bean
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
// 把bean的属性设置进去,主要是名字
sbd.setSource(resource);
// 独立的非接口非抽象类的普通类,或者@Lookup注解的抽象类
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
// 添加到返回的符合扫描的候选bean集合中
candidates.add(sbd);
} else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
} catch (FileNotFoundException ex) {
if (traceEnabled) {
logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
}
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
isCandidateComponent判断是不是bean
- 和排除过滤器匹配,如果匹配成功则此.class不是扫描的bean
- 先和之前注册的扫描过滤@Component匹配,再判断@Conditional的条件是否满足
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
4、注册配置类(Config.class)
- register(componentClasses);将配置类转为BeanDefinition放入bean容器
- 配置类bean添加到
beanDefinitionMap
中,与默认后置处理器存放在一起
三、总结
- 本篇文章主要讲述刷新上下文前的准备工作
- 创建bean工厂容器,也就是map对象,以后缓存单例对象
- 添加常用注册bean和解析注解的后置处理器
- new扫描包的类,根据包路径扫描Component的bean
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/148522.html