基于 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);
}

猜你喜欢

转载自blog.csdn.net/qq_44226094/article/details/119120718