基于 Annotation 的 IOC 初始化
定位 Bean 扫描路径
AnnotationConfigApplicationContext
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
/**
* 保存一个读取注解的Bean定义读取器,并将其设置到容器中
*/
private final AnnotatedBeanDefinitionReader reader;
/**
* 保存一个扫描指定类路径中注解 Bean 定义的扫描器, 并将其设置到容器中
*/
private final ClassPathBeanDefinitionScanner scanner;
}
/**
* 最常用的构造函数,通过将涉及到的配置类传递给该构造函数,
* 以实现将相应配置类中的Bean自动注册到容器中
* @param annotatedClasses
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
/**
* 为容器注册一个要被处理的注解Bean,新注册的Bean,必须手动调用容器的
* refresh()方法刷新容器,触发容器对新注册的Bean的处理
* @param annotatedClasses one or more annotated classes,
*/
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
读取 Annotation 元数据
AnnotatedBeanDefinitionReader
通过调用注解 Bean 定义读取器
/**
* 注册多个注解Bean定义类
* @param annotatedClasses
*/
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
/**
* 注册一个注解Bean定义类
* @param annotatedClass
*/
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
/**
* Bean定义读取器向容器注册注解Bean定义类
* @param annotatedClass
* @param instanceSupplier
* @param name
* @param qualifiers
* @param definitionCustomizers
* @param <T>
*/
<T> void doRegisterBean(Class<T> annotatedClass,
@Nullable Supplier<T> instanceSupplier,
@Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers,
BeanDefinitionCustomizer... definitionCustomizers) {
//解析注解Bean定义的作用域,若@Scope("prototype"),则Bean为原型类型;
//若@Scope("singleton"),则Bean为单态类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//处理注解Bean定义中的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//根据注解Bean定义类中配置的作用域,创建相应的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//向IOC容器注册注解Bean类定义对象
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
AnnotationScopeMetadataResolver
解析作用域元数据
/**
* 解析注解Bean定义类中的作用域元信息
* @param definition the target bean definition
* @return
*/
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
}
AnnotationConfigUtils
扫描二维码关注公众号,回复:
13228179 查看本文章
处理注解 Bean 定义类中的通用注解
/**
* 处理Bean定义中通用注解
* @param abd
* @param metadata
*/
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
}
根据注解 Bean 定义类中配置的作用域为其应用相应的代理策略
/**
* 根据作用域为Bean应用引用的代码模式
* @param metadata
* @param definition
* @param registry
* @return
*/
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils
向容器注册 Bean
/**
* 将解析的BeanDefinitionHold注册到容器中
* @param definitionHolder
* @param registry
* @throws BeanDefinitionStoreException
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
}
扫描指定包并解析为 BeanDefinition
ClassPathBeanDefinitionScanner
扫描给定的包及其子包
/**
* 调用类路径Bean定义扫描器入口方法
* @param basePackages
* @return
*/
public int scan(String... basePackages) {
//启动扫描器扫描给定包
doScan(basePackages);
}
/**
* 类路径Bean定义扫描器扫描给定包及其子包
* @param basePackages
* @return
*/
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
//扫描给定类路径,获取符合条件的Bean定义
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
}
ClassPathScanningCandidateComponentProvider
扫描给定包及其子包的类
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
//保存过滤规则要包含的注解, 即 Spring 默认的@Component、 @Repository、 @Service、
//@Controller 注解的 Bean, 以及 JavaEE6 的@ManagedBean 和 JSR-330 的@Named 注解
private final List<TypeFilter> includeFilters = new LinkedList<>();
//保存过滤规则要排除的注解
private final List<TypeFilter> excludeFilters = new LinkedList<>();
}
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {
//如果使用Spring默认的过滤规则,则向容器注册过滤规则
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(null);
}
/**
* 向容器注册过滤规则
*/
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
//向要包含的过滤规则中添加@Component注解类,注意Spring中@Repository
//@Service和@Controller都是Component,因为这些注解都添加了@Component注解
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
}
/**
* 扫描给定类路径的包
* @param basePackage
* @return
*/
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
private Set<BeanDefinition> addCandidateComponentsFromIndex(CandidateComponentsIndex index, String basePackage) {
//如果扫描到的类符合容器配置的过滤规则
if (isCandidateComponent(metadataReader)) {
}
}
/**
* 判断元信息读取器读取的类是否符合容器定义的注解过滤规则
* @param metadataReader
* @return
* @throws IOException
*/
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
}
注册注解 BeanDefinition
AnnotationConfigWebApplicationContext
/**
* 载入注解Bean定义资源
* @param beanFactory the bean factory to load bean definitions into
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
//为容器设置注解 Bean 定义读取器
AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
//为容器设置类路径 Bean 定义扫描器
ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);
}