<context:component-scan base-package="com.zhuguang.jack" <!-- 扫描的基本包路径 -->
annotation-config="true" <!-- 是否激活属性注入注解 -->
name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator" <!-- Bean的ID策略生成器 -->
resource-pattern="**/*.class" <!-- 对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行 -->
scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" <!-- scope解析器 ,与scoped-proxy只能同时配置一个 -->
scoped-proxy="no" <!-- scope代理,与scope-resolver只能同时配置一个 -->
use-default-filters="false" <!-- 是否使用默认的过滤器,默认值true -->
>
<!-- 注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖 -->
<!-- annotation是对注解进行扫描 ,有这个注解的才会扫描实例化-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
<!-- assignable是对类或接口进行扫描 ,实现这个接口的才会扫描实例化-->
<context:include-filter type="assignable" expression="com.wjx.betalot.performer.Performer"/>
<context:include-filter type="assignable" expression="com.wjx.betalot.performer.impl.Sonnet"/>
<context:exclude-filter type="regex" expression=".controller.*"/>
<!-- 注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除,
有Controller注解的排除,
-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="assignable" expression="com.wjx.betalot.performer.impl.RainPoem"/>
<context:exclude-filter type="regex" expression=".service.*"/>
</context:component-scan>
public BeanDefinition parse(Element element, ParserContext parserContext) {
String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); //[com.zhuguang.jack] ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); //扫描器
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null;
}
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
XmlReaderContext readerContext = parserContext.getReaderContext(); //XmlReaderContext@704deff2
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)); //默认过滤器
}
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters); //扫描器
return scanner;
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage); // [[AnnotationServiceImpl];], [CommonController]; ]],
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); //往bean定义里面设置属性,setLazyInit,setAutowireMode,setDependencyCheck,setInitMethodName,setEnforceInitMethod,setDestroyMethodName,setEnforceDestroyMethod都设置默认值,
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); //往bean定义里面设置属性,是否有Lazy,Primary,DependsOn,Role,Description注解,如果有就设置到bean定义中去。
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //把BeanDefinition 变成BeanDefinitionHolder,
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry); //注册到spring容器中,
}
}
}
return beanDefinitions;
}
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + "/" + this.resourcePattern; //classpath*:com/zhuguang/jack/**/*.class找到所有的。class文件,
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); //[file [E:AnnotationServiceImpl.class], file [E:CommonController.class], file [E:CommonMapper.class], file [E:ConsultConfigArea.class], file [E:ConsultContent.class], file [E:MyService.class], file [E:Test2.class], file [E:User.class]]
for (Resource resource : resources) {
if (isCandidateComponent(metadataReader) && resource.isReadable()) { //没有条件注解,就进来,没有注解的不进来。有@Component注解的才进来,
try {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); //AnnotationMetadata里面封装了这个类的一些基本信息,类里面有哪些方法,方法上面有哪些注解,类上面有哪些注解,
if (isCandidateComponent(metadataReader)) {//!(this.isInterface || this.isAbstract) && (this.enclosingClassName == null || this.independentInnerClass); 不是接口不是抽象类就进来,CommonMapper是一个接口不进来,
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
candidates.add(sbd);
}
else {
}
}
}
}
}
}
return candidates;
}
public MetadataReader getMetadataReader(Resource resource) throws IOException {
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException {
InputStream is = new BufferedInputStream(resource.getInputStream());//文件流,
ClassReader classReader;
classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader);
classReader.accept(visitor, ClassReader.SKIP_DEBUG); this.annotationMetadata = visitor;
this.classMetadata = visitor;
this.resource = resource;
}
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {  //metadataReader是类的元数据信息,
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {//interface org.springframework.stereotype.Component,interface javax.inject.Named。有@Component注解的才进来,
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return isConditionMatch(metadataReader);
}
}
return false;
}
public Resource[] getResources(String locationPattern) throws IOException {
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
return findPathMatchingResources(locationPattern);
}
}
}
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
String rootDirPath = determineRootDir(locationPattern); //classpath*:com/zhuguang/jack/
String subPattern = locationPattern.substring(rootDirPath.length()); //**/*.class
Resource[] rootDirResources = getResources(rootDirPath); //返回[URL [file:/E:/Code/AAAAA/AAAAA/2019326/2/spring-source-web-master-aop/target/classes/com/zhuguang/jack/]]
Set<Resource> result = new LinkedHashSet<Resource>();
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource); //返回[URL [file:/E:/Code/AAAAA/AAAAA/2019326/2/spring-source-web-master-aop/target/classes/com/zhuguang/jack/]]
if (isJarResource(rootDirResource)) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
}
else if (rootDirResource.getURL().getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirResource, subPattern, getPathMatcher()));
}
else {
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}
}
return result.toArray(new Resource[result.size()]); //[file [E:AnnotationServiceImpl.class], file [E:CommonController.class], file [E:CommonMapper.class], file [E:ConsultConfigArea.class], file [E:ConsultContent.class], file [E:MyService.class], file [E:Test2.class], file [E:User.class]]
}
public Resource[] getResources(String locationPattern) throws IOException {
else {
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
} protected Resource[] findAllClassPathResources(String location) throws IOException {
Enumeration<URL> resourceUrls = getClassLoader().getResources(path); //AppClassLoader,返回[sun.misc.CompoundEnumeration@b83a9be, java.net.URLClassLoader$3@2609b277]
Set<Resource> result = new LinkedHashSet<Resource>();
while (resourceUrls.hasMoreElements()) {
URL url = resourceUrls.nextElement();
result.add(convertClassLoaderURL(url));
}
return result.toArray(new Resource[result.size()]); //返回[URL [file:/E:/Code/AAAAA/AAAAA/2019326/2/spring-source-web-master-aop/target/classes/com/zhuguang/jack/]]
}
public Enumeration<URL> getResources(String name) throws IOException {
@SuppressWarnings("unchecked")
Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[];
if (parent != null) {
tmp[] = parent.getResources(name); //ExtClassLoader
} else {
tmp[] = getBootstrapResources(name);
}
tmp[] = findResources(name); return new CompoundEnumeration<>(tmp);
}
private static Enumeration<URL> getBootstrapResources(String name)   {
final Enumeration<Resource> e = getBootstrapClassPath().getResources(name); //sun.misc.URLClassPath@28d18df5
return new Enumeration<URL> () {
public URL nextElement() {
return e.nextElement().getURL();
}
public boolean hasMoreElements() {
return e.hasMoreElements();
}
}
}

spring context:component-scan的更多相关文章

  1. [Spring Boot] Use Component Scan to scan for Bean

    Component Scan is important concept when we want to create Bean. Currently we know what, for the cla ...

  2. Spring注解Component原理源码解析

    在实际开发中,我们经常使用Spring的@Component.@Service.@Repository以及 @Controller等注解来实现bean托管给Spring容器管理.Spring是怎么样实 ...

  3. Spring context:component-scan中使用context:include-filter和context:exclude-filter

    Spring context:component-scan中使用context:include-filter和context:exclude-filter XML: <?xml version= ...

  4. Spring context:component-scan代替context:annotation-config

    Spring context:component-scan代替context:annotation-config XML: <?xml version="1.0" encod ...

  5. Spring <context:annotation-config> 与<context-component-scan> 的作用

    <context:annotation-config> 与<context-component-scan> 的作用 <context:annotation-config& ...

  6. Spring <context:component-scan>标签属性 use-default-filters 以及子标签 include-filter使用说明

    Spring <context:component-scan>标签作用有很多,最基本就是 开启包扫描,可以使用@Component.@Service.@Component等注解: 今天要作 ...

  7. Spring 注解@Component,@Service,@Controller,@Repository

    Spring 注解@Component,@Service,@Controller,@RepositorySpring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释, ...

  8. [转载]vs2012中使用Spring.NET报错:Spring.Context.Support.ContextRegistry 的类型初始值设定项引发异常

    学习使用Spring.NET中的时候,写了一个Demo,在运行时报了一个错误:Spring.Context.Support.ContextRegistry 的类型初始值设定项引发异常. 重新整理思绪, ...

  9. 使用web.xml方式加载Spring时,获取Spring context的两种方式

    使用web.xml方式加载Spring时,获取Spring context的两种方式: 1.servlet方式加载时: [web.xml] <servlet> <servlet-na ...

  10. 【报错】spring整合activeMQ,pom.xml文件缺架包,启动报错:Caused by: java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler

    spring版本:4.3.13 ActiveMq版本:5.15 ======================================================== spring整合act ...

随机推荐

  1. CentOs安装mysql数据库

    1. 下载 http://dev.mysql.com/downloads/mysql/ 或者使用wget下载: wget http://dev.mysql.com/get/Downloads/MySQ ...

  2. python多进程multiprocessing Pool相关问题

    python多进程想必大部分人都用到过,可以充分利用多核CPU让代码效率更高效. 我们看看multiprocessing.pool.Pool.map的官方用法 map(func, iterable[, ...

  3. 【linux】linux命令lsof和grep命令的配合使用---linux根据端口查看PID,根据PID关键字高亮显示

    lsof命令,根据端口,查看进程PID lsof -i: ps命令+grep命令 --color参数,根据PID查看进程详情,高亮显示关键字 ps -ef | grep --color=always

  4. oracle学习笔记(十一) 高级查询

    高级查询 分组查询 select * from student [where ] [having ] --二次限定 [order by] --asc升序 desc降序 默认升序 查看EMPLOYEE表 ...

  5. MySQL(9)---纪录一次实际开发过程中用到的复杂存储过程

    Mysql(9)---纪录一次实际开发过程中用到的复杂存储过程 为了尽可能的还原当时为什么需要用到存储过程,下面我写了个详细的文档,我们可以从需求文档出发来分析. 有关存储过程之前也写了两篇文章来做铺 ...

  6. Define the Data Model and Set the Initial Data 定义数据模型并设置初始数据

    This topic describes how to define the business model and the business logic for WinForms and ASP.NE ...

  7. docker下安装Redis

    Docker介绍 1.节约时间.快速部署和启动 2.节约成本 3.标准化应用发布 4.方便做持续继承 5作为集群中的轻量主机或节点 6.方便构建基于SOA或者微服务架构的系统 Docker中文文档 h ...

  8. DesignPattern系列__08UML相关知识

    前言 现在,很少有人和90年代一样,自己去实现一个软件的各个方面,也就是说,在工作中,和人沟通是必备的技能.那么,作为一枚码农,如何和他人沟通呢?这就要依靠本文的主题了--UML. 简介 UML--U ...

  9. 工具类Base64Util

    在和服务器交互的过程中,有时候我们需要把图片编码成base64字符串传输,记录一下工具类 import android.graphics.Bitmap; import android.graphics ...

  10. Excel 扩展编程相关

    ============================产品分析============================Excel Automation Tools (Best of List)htt ...