@ComponentScan
如果你理解了ComponentScan,你就理解了Spring.
Spring是一个依赖注入(dependency injection)框架。所有的内容都是关于bean的定义及其依赖关系。
定义Spring Beans的第一步是使用正确的注解-@Component或@Service或@Repository.
但是,Spring不知道你定义了某个bean除非它知道从哪里可以找到这个bean.
ComponentScan做的事情就是告诉Spring从哪里找到bean
由你来定义哪些包需要被扫描。一旦你指定了,Spring将会将在被指定的包及其下级的包(sub packages)中寻找bean
下面分别介绍在Spring Boot项目和非Spring Boot项目(如简单的JSP/Servlet或者Spring MVC应用)中如何定义Component Scan
Spring Boot项目
总结:
- 如果你的其他包都在使用了@SpringBootApplication注解的main app所在的包及其下级包,则你什么都不用做,SpringBoot会自动帮你把其他包都扫描了
- 如果你有一些bean所在的包,不在main app的包及其下级包,那么你需要手动加上@ComponentScan注解并指定那个bean所在的包
-
举个栗子,看下面定义的类
package com.in28minutes.springboot.basics.springbootin10steps; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class SpringbootIn10StepsApplication { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(SpringbootIn10StepsApplication.class, args); for (String name : applicationContext.getBeanDefinitionNames()) { System.out.println(name); } } }
-
类
SpringbootIn10StepsApplication
在com.in28minutes.springboot.basics.springbootin10steps
包下,这个类使用了@SpringBootApplication
注解,该注解定义了Spring将自动扫描包com.in28minutes.springboot.basics.springbootin10steps
及其子包下的bean如果你项目中所有的类都定义在上面的包及其子包下,那你不需要做任何事。
但假如你一个类定义在包
com.in28minutes.springboot.somethingelse
下,则你需要将这个新包也纳入扫描的范围,有两个方案可以达到这个目的。 -
方案1
定义@CoponentScan(“com.in28minutes.springboot”)
这么做扫描的范围扩大到整个父包com.in28minutes.springboot
@ComponentScan(“com.in28minutes.springboot”) @SpringBootApplication public class SpringbootIn10StepsApplication {
- 1
- 2
- 3
-
方案2
定义分别扫描两个包
@ComponentScan({“com.in28minutes.springboot.basics.springbootin10steps”,”com.in28minutes.springboot.somethingelse”})@ComponentScan({"com.in28minutes.springboot.basics.springbootin10steps","com.in28minutes.springboot.somethingelse"}) @SpringBootApplication public class SpringbootIn10StepsApplication {
- 1
- 2
- 3
-
@ComponentScan({"com.in28minutes.package1","com.in28minutes.package2"}) @Configuration public class SpringConfiguration {
- 1
- 2
- 3
-
XML文件方式
<context:component-scan base-package="com.in28minutes.package1, com.in28minutes.package2" />
非Spring Boot项目
在非Spring Boot项目中,我们必须显式地使用@ComponentScan注解定义被扫描的包,可以通过XML文件在应用上下文中定义或在Java代码中对应用上下文定义
Java代码方式
-
@ComponentScan({"com.in28minutes.package1","com.in28minutes.package2"}) @Configuration public class SpringConfiguration {
- 1
- 2
- 3
-
XML文件方式
<context:component-scan base-package="com.in28minutes.package1, com.in28minutes.package2" />
@Component and @ComponentScan 的区别
@Component 和 @ComponentScan的使用目的不一样
- 在某个类上使用@Component注解,表明当需要创建类时,这个被注解的类是一个候选类。就像是举手。
- @ComponentScan 用于扫描指定包下的类。就像看都有哪些举手了。