ComponentScan
一、@ComponentScan注解是什么
如果你理解了ComponentScan,你就理解了Spring是一个依赖注入(dependency injection)框架。所有的内容都是关于bean的定义及其依赖关系。
定义Spring Beans的第一步是使用正确的注解@Component或@Service或@Repository或者@Controller
但是,Spring不知道你定义了某个bean除非它知道从哪里可以找到这个bean
ComponentScan做的事情就是告诉Spring从哪里找到bean
由你来定义哪些包需要被扫描。一旦你指定了,Spring将会在被指定的包及其下级包中寻找bean
下面分别介绍在Spring Boot项目和非Spring Boot项目(如简单的JSP/Servlet或者Spring MVC应用)中如何定义@Component Scan
二、@ComponentScan注解的基本使用
1.Spring Boot项目
总结:
- 如果你的其他包都在使用了@SpringBootApplication注解的main
app所在的包及其下级包中,则你什么都不用做,SpringBoot会自动帮你把其他包都扫描了 - 如果你有一些bean所在的包,不在main
app的包及其下级包中,那么你需要手动加上@ComponentScan注解并指定那个bean所在的包
举个例子,看下面定义的类
package com.demo.springboot;@SpringBootApplication
public class SpringbootApplication {public static void main(String[] args) {ApplicationContext applicationContext = SpringApplication.run(SpringbootApplication .class, args);for (String name : applicationContext.getBeanDefinitionNames()) {System.out.println(name);}}
}
类 SpringbootApplication 在com.demo.springboot包下,这个类使用了@SpringBootApplication注解,该注解定义了Spring将自动扫描包com.demo.springboot及其子包下的bean
如果你项目中所有的类都定义在com.demo.springboot包及其子包下,那你不需要做任何事
但假如你一个类定义在包com.demo.somethingelse下,则你需要将这个新包也纳入扫描的范围,有两个方案可以达到这个目的。
方案1
定义@CoponentScan(“com.demo”)
这么做扫描的范围扩大到整个父包com.demo
@ComponentScan(“com.demo”)
@SpringBootApplication
public class SpringbootApplication {
方案2
定义分别扫描两个包
@ComponentScan({“com.demo.springboot”,”com.demo.somethingelse”})
@ComponentScan({"com.demo.springboot","com.demo.somethingelse"})
@SpringBootApplication
public class SpringbootApplication {
特别注意一下:如果使用了方案2,如果仅仅只写@ComponentScan({"com.demo.somethingelse"})将导致com.demo.springboot包下的类无法被扫描到(框架原始的默认扫描效果无效了)
2.非Spring Boot项目
在非Spring Boot项目中,我们必须显式地使用@ComponentScan注解定义被扫描的包,可以通过XML文件在应用上下文中定义或在Java代码中对应用上下文定义
Java代码方式
@ComponentScan({"com.demo.package1","com.demo.package2"})
@Configuration
public class SpringConfiguration {
XML文件方式
<context:component-scan base-package="com.demo.package1, com.demo.package2"/>
三、@ComponentScan注解说明
@ComponentScan:会自动扫描包路径下面的所有被@Controller、@Service、@Repository、@Component 注解标识的类,然后装配到Spring容器中。
@ComponentScan的属性: value指定扫描的包,includeFilters包含那些过滤,excludeFilters不包含那些过滤,useDefaultFilters默认的过滤规则是开启的,如果我们要自定义的话是要关闭的。其中@Filters是一个过滤器的接口。
@Filters 指过滤规则,FilterType指定过滤的规则
FilterType.ANNOTATION:按照注解FilterType.ASSIGNABLE_TYPE:按照给定的类型;FilterType.ASPECTJ:使用ASPECTJ表达式FilterType.REGEX:使用正则指定FilterType.CUSTOM:使用自定义规则)classes指定过滤的类
1.基本示例:
创建controller:
@Controller
public class UserController {
}
创建service:
@Service
public class UserService {
}
创建dao:
@Repository
public class UserDao {
}
添加启动类:
@Configuration
@ComponentScan(value = "com.spring.annotation")
public class ScanConfig {}
测试:
@Testpublic void test02() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScanConfig.class);String[] beanDefinitionNames = context.getBeanDefinitionNames();for (String name : beanDefinitionNames) {System.out.println(name);}}
结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactoryscanConfig
annotationConfig
userController
userDao
userService
可以看到对应的实体类已经注入到容器中
2.过滤指定的注解进行注入
- excludeFilters (排除过滤器)
@Configuration
@ComponentScan(value = "com.spring.annotation",excludeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class})
})
public class ScanConfig{}
@ComponentScan.Filter 指定了过滤器的规则,FilterType.ANNOTATION 表示按注解过滤,classes指定需要过滤的注解,Controller注解被排除,classes为数组可以指定多个,重新运行结果:
scanConfig
annotationConfig
userDao
userService
可以看到 原来的 userController 已经消失,说明没有被注入到容器中去
- includeFilters (包含过滤器)
@Configuration
@ComponentScan(value="com.spring.annotation",
// excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})}includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = false
)
public class ScanConfig {
}
运行结果:
scanConfig
userController
可以看到只有 被@controller注解的bean注入到容器中去。useDefaultFilters默认的过滤规则是开启的,如果我们要自定义的话是要关闭的;
ComponentScan相关推荐
- 在SpringBoot启动类上添加ComponentScan出现springbootapplication already applies given @ComponentScan
查看@SpringBootApplication注解源码,可以看到 @SpringBootApplication=@Configuration+@EnableAutoConfiguration+@Co ...
- component-scan和annotation-driven
<context:component-scan/> 该xml配置作用是启动Spring的组件扫描功能,自动扫描base-package指定的包及其子文件下的java文件,如果扫描到有@co ...
- Spring component-scan类扫描加载过程
2019独角兽企业重金招聘Python工程师标准>>> https://github.com/javahongxi 有朋友最近问到了spring加载类的过程,尤其是基于annotat ...
- Spring配置中context:annotation-config VS context:component-scan
Spring 中在使用注解(Annotation)会涉及到< context:annotation-config> 和 < context:component-scan>配置, ...
- SpringBoot—— @ComponentScan
2019独角兽企业重金招聘Python工程师标准>>> SpringBoot在写启动类的时候如果不使用@ComponentScan指明对象扫描范围,默认指扫描当前启动类所在的包里的对 ...
- springboot 启动类注解 @SpringBootApplication 和 @ComponentScan 的问题
问题: 在启动类Application上使用@ComponentScan 这个注解来扫描第三方的包,然后就会出现报错,异常就是无法加载本地的某些类,例如某些Dao无法注入. 分析: 启动类注解 @Sp ...
- Spring context:component-scan代替context:annotation-config
Spring context:component-scan代替context:annotation-config XML: <?xml version="1.0" encod ...
- 组件注册——@ComponentScan自动扫描组件指定扫描规则
包扫描.只要标注了@Controller.@Service.@Repository,@Component IOCTest.java package com.atguigu.test;import or ...
- Spring的新注解——Configuration、ComponentScan、Bean、Import、PropertySource || spring整合Junit分析
spring中的新注解 spring整合Junit分析 1.应用程序的入口 main方法 2.junit单元测试中,没有main方法也能执行 junit集成了一个main方法 ...
- spring源码分析之context:component-scan/vsannotation-config/
1.<context:annotation-config/> xsd中说明: <xsd:element name="annotation-config"> ...
最新文章
- 运用Hibernate-Tools自动生成Java类和schema时,出现not found while looking for property...异常...
- leetcode 216. 组合总和 III 思考分析
- 小甲鱼 OllyDbg 教程系列 (十) : Windows 逆向常用 api 以及 XOFTSPY 逆向
- python 网络维护_python学习之网络基础
- 阿里云linux主机更新hostname
- IT小公司避坑及生存指南
- DirectShow简介
- 机组0:为什么补码比原码多一个-128清晰解释
- Kubernetes init 提示 [ERROR ImagePull]: failed to pull image registry.aliyuncs.com/google_containers/c
- TR CEV65M-01460一个人,也有春夏秋冬
- CAD的那些装逼技巧!
- 【Java 数据结构】Map和Set
- 斐讯n1盒子装网易音乐命令版
- JavaScript - 语言基础
- Python读取键盘输入到一维列表及二维列表
- 前端程序员和后端程序员有什么不同?我来告诉你薪资待遇差多少
- iOS中几种数据持久化方案-转自简书
- GROUP BY无法运行解决办法
- “您可能是软件盗版的受害者”的解决方法
- 云原生服务网格Istio:原理、实践、架构与源码解析
热门文章
- onclick 阻止冒泡
- Python 直连打印机打印,可排版设置字体,附标签贴打印案例。
- Matlab:矩阵分解
- DECANTeR: DEteCtion of Anomalous outbouNd HTTP TRaffic by Passive Application Fingerprinting
- 九联UNT402A_S905L_S905L3通刷版线刷固件包及优盘刷机包
- 扫地僧Backtrader给力教程:量化回测核心篇(全集)
- html全排列,JavaScript全排列的六种算法 具体实现
- TI AM3552开发板(arm cortex A8) 初体验
- 左耳听风ARTS第2周
- OpenMMLab AI实战营第二期|人体关键点检测与MMPose学习笔记