• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

Spring中@Component和@ComponentScan注解用法介绍和注意事项

开发技术 开发技术 4小时前 1次浏览

Component Scan是什么?
为什么ComponentScan很重要?
项目中Spring Boot会对哪些包自动执行扫描(Component Scan)?
如何利用Spring Boot定义扫描范围?
项目启动时关于Component Scan的常见报错
@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.demo.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;

@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);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
类 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 {
1
2
3
方案2
定义分别扫描两个包
@ComponentScan({“com.demo.springboot”,”com.demo.somethingelse”})

@ComponentScan({“com.demo.springboot”,”com.demo.somethingelse”})
@SpringBootApplication
public class SpringbootApplication {
1
2
3
特别注意一下:如果使用了方案2,如果仅仅只写@ComponentScan({“com.demo.somethingelse”})将导致com.demo.springboot包下的类无法被扫描到(框架原始的默认扫描效果无效了)

非Spring Boot项目
在非Spring Boot项目中,我们必须显式地使用@ComponentScan注解定义被扫描的包,可以通过XML文件在应用上下文中定义或在Java代码中对应用上下文定义

Java代码方式

@ComponentScan({“com.demo.package1″,”com.demo.package2”})
@Configuration
public class SpringConfiguration {
1
2
3
XML文件方式

<context:component-scan base-package=”com.demo.package1, com.demo.package2″/>
1
项目中常见关于Component Scan的报错
你是否在项目启动中遇到过类似这样的报错:

WARNING: No mapping found for HTTP request with URI [/spring-mvc/login] in DispatcherServlet with name ‘dispatcher’

WARNING: No mapping found for HTTP request with URI [/list-todos] in DispatcherServlet with name ‘dispatcher’

或者:

ERROR:No qualifying bean of type [com.demo.springboot.jpa.UserRepository] found for dependency [com.demo.springboot.jpa.UserRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}…

报错的根因都是bean没有被Spring找到
遇到这些错误你应该检查:

你是否给类加了正确的注解@Controller,@Repository,@Service或@Component
你是否在应用上下文定义了Component Scan
报错类所在的包是否在Component Scan中指定的包的范围
@Component 和@ComponentScan 的区别
@Component 和 @ComponentScan的使用目的不一样

在某个类上使用@Component注解,表明当需要创建类时,这个被注解的类是一个候选类。就像是举手。
@ComponentScan用于扫描指定包下的类。就像看都有哪些举手了。

 

今天在写程序的时候看见一个以前没有见过的注解(@Component),在网上查找过后,经过实践,决定把它记录下来。
1、@controller 控制器(注入服务)

用于标注控制层,相当于struts中的action层
2、@service 服务(注入dao)

用于标注服务层,主要用来进行业务的逻辑处理
3、@repository(实现dao访问)

用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件.
4、@component (把普通pojo实例化到spring容器中,相当于配置文件中的
<bean id=”” class=””/>)

泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。
案例:
<context:component-scan base-package=”com.*”>
上面的这个例子是引入Component组件的例子,其中base-package表示为需要扫描的所有子包。
共同点:被@controller 、@service、@repository 、@component 注解的类,都会把这些类纳入进spring容器中进行管理


程序员灯塔
转载请注明原文链接:Spring中@Component和@ComponentScan注解用法介绍和注意事项
喜欢 (0)