Springboot注解@ServletComponentScan和@ComponentScan(转)

1、SpringBoot中使用Servlet
在SpringBootApplication上使用@ServletComponentScan注解后,Servlet、Filter、Listener能够直接经过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其余代码。html

1.在入口Application类上加入注解@ServletComponentScanjava

package com.hui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication @ServletComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

2.新建Servlet类,继承HttpServlet而且加入注解@WebServlet(name=“TestServlet”,urlPatterns="/test")web

package com.hui.qiang; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="TestServlet",urlPatterns="/test") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); } }

3.以后运行代码,在浏览器地址栏输入http://localhost:8080/test,若看到控制台打印doGet,则表示Servlet建立成功。
注意:
(1)若是不加@ServletComponentScan注解则会报404即找不到页面,控制台也扫描不到咱们配置的servlet:/test,即没法被映射
(2)若是Application类和Servlet类不在同一包下,则@ServletComponentScan须要添加相应的路径,如Application类在包com.hui.xiao下,则写为@ServletComponentScan(“com.hui.xiao”)或@ServletComponentScan(“com.hui”)spring

 

 

 

 

2、Spring, Spring Boot中的@ComponentScan注解用法介绍
@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应用)中如何定义ComponentScanapp

注:@ComponentScan的不一样写法
1.@ComponentScan({“com.xiao.hui”,“com.xiao.qiang”})或@ComponentScan(basePackages = {“com.xiao.hui”,“com.xiao.qiang”})
2.@ComponentScan(“com.xiao”)或@ComponentScan(value = “com.xiao”)或@ComponentScan(basePackages = { “com.xiao” })
3.@ComponentScan(basePackageClasses=要扫描类.class所在位置的包) 意思是要扫描哪一个类所在的包,如@ComponentScan(basePackageClasses=hehe.class),这种写法不如上面的那种写法好有局限性框架

Spring Boot项目
总结:
1.SpringBoot在写启动类的时候若是不使用@ComponentScan指明对象扫描范围,默认指扫描当前启动类所在的包里的对象,若是你的其余包都在使用了@SpringBootApplication注解的主类所在的包及其下级包,则你什么都不用作,SpringBoot会自动帮你把其余包都扫描了。为了方便,我通常都把主类放在了全部类的上一级包中,如项目全部的class文件都放在了包com.beauty的下级包中,则把spring boot的主类放在包com.beauty下。
2.若是当前启动类没有包,则在启动时会报错:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package错误,由于启动类不能直接放在main/java文件夹下,必需要建一个包把它放进去或者使用@ComponentScan指明要扫描的包。
3.若是你有一些bean所在的包,不在主类的包及其下级包,那么你须要手动加上@ComponentScan注解并指定那个bean所在的包。ide

举个栗子,看下面定义的类:测试

package com.xiao.qiang.qianming; 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); } } }

类SpringbootApplication在com.xiao.qiang.qianming包下,这个类使用了@SpringBootApplication注解,该注解定义了Spring将自动扫描包com.xiao.qiang.qianming及其子包下的bean
若是你项目中全部的类都定义在上面的包及其子包下,那你不须要作任何事。
但假如你一个类定义在包com.xiao.hui下,则你须要将这个新包也归入扫描的范围,有两个方案能够达到这个目的。ui

方案1
定义@ComponentScan(“com.xiao”),这么作扫描的范围扩大到整个父包com.xiao

@ComponentScan("com.xiao") @SpringBootApplication public class SpringbootIn10StepsApplication {

方案2
定义分别扫描两个包

@ComponentScan({"com.xiao.hui","com.xiao.qiang"}) @SpringBootApplication public class SpringbootIn10StepsApplication {

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

Java代码方式:

@ComponentScan({"com.xiao.package1","com.xiao.package2"}) @Configuration public class SpringConfiguration {

注:@Configuration 和@ComponentScan注解背后会作什么呢?
其实很简单,@ComponentScan告诉Spring 哪一个packages 的用注解标识的类 会被spring自动扫描而且装入bean容器。
例如,若是你有个类用@Controller注解标识了,那么,若是不加上@ComponentScan,自动扫描该controller,那么该Controller就不会被spring扫描到,更不会装入spring容器中,所以你配置的这个Controller也没有意义。
类上的注解@Configuration 是最新的用注解配置spring,也就是说这是个配置文件,和原来xml配置是等效的,只不过如今用java代码进行配置了 加上一个@Configuration注解就好了,是否是很方便,不须要那么繁琐的xml配置了,这样基于注解的配置,可读性也大大增高了。

XML文件方式:
<context:component-scan base-package=“com.xiao.package1, com.xiao.package2” />
 

3、使用@ComponentScan自动扫描组件实例
包扫描会扫描只要标注了@Controller,@Service,@Repository,@Component这四个注解都会被扫描到容器中。
一、@Controller 控制器(注入服务)
用于标注控制层,至关于struts中的action层
二、@Service 服务(注入dao)
用于标注服务层,主要用来进行业务的逻辑处理
三、@Repository(实现dao访问)
用于标注数据访问层,也能够说用于标注数据访问组件,即DAO组件.
四、@Component (把普通pojo实例化到spring容器中,至关于配置文件中的<bean id="" class=""/>)
泛指各类组件,就是说当咱们的类不属于各类归类的时候(不属于@Controller、@Services等的时候),咱们就可使用@Component来标注这个类。
案例:<context:component-scan base-package=”com.*”>
上面的这个例子是引入Component组件的例子,其中base-package表示为须要扫描的全部子包。
有一篇不错的文章(Spring注解详解):https://blog.csdn.net/xyh820/article/details/7303330/

 

 

 新增控制层的java类:TestController和HelloController

import org.springframework.stereotype.Controller; @Controller public class TestController { }
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping(value="/hello", method = RequestMethod.GET) public String hello() { return "Hello, Spring Boot"; } }

新建一个业务逻辑层类:TestService

import org.springframework.stereotype.Service; @Service public class TestService { }

新建一个Person:

public class Person { public Person(String string, int i) { } }

主方法测试:
spring boot:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(value = "com.hui") public class Application { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(Application.class, args); for (String name : applicationContext.getBeanDefinitionNames()) { System.out.println(name); } } }

非spring boot:

import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.hui.entity.Person; @Configuration @ComponentScan(value = "com.hui") public class ComponentTest { @Bean public Person getPerson() { return new Person("百度好帅", 10000); } public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(ComponentTest.class); String[] beanNames = applicationContext.getBeanDefinitionNames(); for (String bean : beanNames) { System.out.println(bean); } } }

运行Application:
控制台扫描到了/hello,即映射成功

 

 

 

 

 把Application注释掉运行ComponentTest:

 

参考:
https://blog.csdn.net/Lamb_IT/article/details/80918704
https://jingyan.baidu.com/article/7908e85cc6930daf481ad2b6.html

————————————————版权声明:本文为CSDN博主「小强签名设计」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接及本声明。原文连接:https://blog.csdn.net/m0_37739193/article/details/85097477

相关文章
相关标签/搜索