ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-07-22 14:34:40  阅读:167  来源: 互联网

标签:demo Component ComponentScan bean Spring com


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容器中进行管理

标签:demo,Component,ComponentScan,bean,Spring,com
来源: https://www.cnblogs.com/yxb0429/p/15043874.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有