上篇传送门
上篇大体了解了下执行BFPP的过程,BFPP的作用也介绍了,但是并没有深入看下如何实现的,接下来咱们了解下context:component-scan 标签是如何解析的
概述
咱们开发过程中会使用到很多的注解配置等,这些注解必须要被扫描到才能被识别
spring中标签分为几种
分为两种
- 标签
- 自定义标签(除了bean标签外)
源码之前先了解两个类
- DefaultBeanDefinitionDocumentReader 调度者
- BeanDefinitionParserDelegate 解析策略类用于策略模式的指令执行者
- NamespaceHandler 策略抽象,用于制定规范
源码
咱们继续回到DefaultBeanDefinitionDocumentReader.parseBeanDefinitions方法
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//只有解析bean标签的时候才是默认标签,其他事自定义标签
//解析bean标签
parseDefaultElement(ele, delegate);
}else {
//使用策略类解析自定义标签
delegate.parseCustomElement(ele);
}
}
}
BeanDefinitionParserDelegate.parseCustomElement 解析自定义标签,使用策略模式
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
//根据节点名称获取对应命名空间
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
//获取处理器
//具体在spring-context/resources/spring.handlers文件中配置
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
return null;
}
//使用处理器进行解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
DefaultNamespaceHandlerResolver.resolve 得到对应的命令空间的处理器
public NamespaceHandler resolve(String namespaceUri) {
//获取spring-context/META-INF/spring.handlers文件中的缓存
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}else if (handlerOrClassName instanceof NamespaceHandler) {
//如果实例化过了
return (NamespaceHandler) handlerOrClassName;
}else {
String className = (String) handlerOrClassName;
try {
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
//实例化
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
//初始化
namespaceHandler.init();
//替换缓存中的value为对象
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
NamespaceHandlerSupport.parse 使用处理器解析元素标签(使用策略模式)
public BeanDefinition parse(Element element, ParserContext parserContext) {
//获取到标签的解析器 从ContextNamespaceHandler里面获取
BeanDefinitionParser parser = findParserForElement(element, parserContext);
return (parser != null ? parser.parse(element, parserContext) : null);
}
NamespaceHandlerSupport.parse 使用处理器解析元素标签
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//元素标签的名称
String localName = parserContext.getDelegate().getLocalName(element);
//从ContextNamespaceHandler里面定义的多个标签中获取出对应的解析类
//这里获取到的是ComponentScanBeanDefinitionParser
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
ComponentScanBeanDefinitionParser.parse 真正开始解析了
public BeanDefinition parse(Element element, ParserContext parserContext) {
//获取包扫描路径
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
//使用PropertyPlaceholderHelper处理包路径
//处理${}占位符
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
//使用分隔符分割,就是咱们可以在package中写多个路径 如:“com.msg.package2,;com.msg.package2”
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 配置扫描器
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 开始扫描,并创建出BeanDefinitionHolder
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
//开始注册组件
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
ComponentScanBeanDefinitionParser.configureScanner 配置扫描器
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
// 创建一个ClassPathBeanDefinitionScanner类路径扫描器并设置相应的属性
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
//设置BeanDefinitionDefaults对象
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
// 如果指定了 name-generator 属性,设置对应bean名称的生成器 如:<bean class=“xxx.xxx.xxx”> 这个类创建完成后对应的名字是什么(就是id值)
parseBeanNameGenerator(element, scanner);
}catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
try {
// 设置 Scope 解析相关信息
<context:component-scan base-package="com">
<context:exclude-filter type="annotation" expression="com.msg"/>
<context:include-filter type="annotation" expression="com.msg"/>
</context:component-scan>
parseScope(element, scanner);
}catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
// 设置子标签过滤、包含相关信息
parseTypeFilters(element, scanner, parserContext);
return scanner;
}
ClassPathBeanDefinitionScanner.doScan 执行扫描
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) {
// 找到符合条件的Component组件(类上标注了@Component注解)
//classpath*:com/msgqu/debug/**/*.class
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析作用域及是否需要代理作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//生成bean的名称(AnnotationBeanNameGenerator)
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//设置基本属性,lazy、AutowireMode...
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//设置注解信息 Lazy、Primary、DependsOn、Role、Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查是否符合条件 如:是不是已经注册过了
if (checkCandidate(beanName, candidate)) {
// 创建bean定义信息的包装类
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 如果需要代理,重新生成definitionHolder
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//记录扫描后的容器中返回
beanDefinitions.add(definitionHolder);
//注册bean定义信息到工厂中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
ComponentScanBeanDefinitionParser.registerComponents 注册必要的组件
protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
Object source = readerContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
//创建内部bean以及引用
for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
}
// Register annotation config processors, if necessary.
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) {
//注册内部使用的定义信息
Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
}
}
//扩展方法
readerContext.fireComponentRegistered(compositeDef);
}
AnnotationConfigUtils.registerAnnotationConfigProcessors 注册内部使用的对象
方法执行前
方法执行后
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
//对bean工厂做配置
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//定义内部解析的定义信息
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//ConfigurationClassPostProcessor是一个BeanFactory的后置处理器,因此它的主要功能是参与BeanFactory的建造,在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解
//借博主的描述,后面咱们还会详细在invokBFPP方法中讲解
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//支持 @Autowired 和 @Value 注解的支持也支持 @Inject 注解,也可以给setter 方法进行注入。也包括对 @Lookup 注解解析
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));
}
//对@PostConstruct和@PreDestroy注解的处理,完成bean初始化前和销毁前的回调
//对@Resource注解的处理,完成依赖字段的注入
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));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
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));
}
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));
}
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;
}