`
y806839048
  • 浏览: 1126311 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Springboot注解@ServletComponentScan和@ComponentScan

阅读更多
总结:
传统项目配置文件和springboot注解的对应

web.xml中的配置注入用@ServletComponentScan 开启,然后在具体注入类结合具体的注入类别注解(servlet,filter,listener)

spring.xml中bean配置用@ComponentScan 开启,可识别@Controller,@servcie ,@Resporsitory等

spring.xml用@configuration 结合@bean


一、SpringBoot中使用Servlet

在SpringBootApplication上使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。



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



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")



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, Spring Boot中的@ComponentScan注解用法介绍

@ComponentScan

如果你理解了ComponentScan,你就理解了Spring.

Spring是一个依赖注入(dependency injection)框架。所有的内容都是关于bean的定义及其依赖关系。

但是,Spring不知道你定义了一个bean,或者它知道从哪里可以获取这个bean.

定义Spring Beans的第一步是使用正确的注解-@Component或@Service或@Repository.



ComponentScan做的事情就是告诉Spring从哪里找到bean


由你来定义哪些包需要被扫描。一旦你指定了,Spring将会将在被指定的包及其下级的包(sub packages)中寻找bean

下面分别介绍在Spring Boot项目和非Spring Boot项目(如简单的JSP/Servlet或者Spring MVC应用)中如何定义ComponentScan


注:@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所在的包。



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



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下,则你需要将这个新包也纳入扫描的范围,有两个方案可以达到这个目的。



方案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 {

1

2

3

非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” />







三、使用@ComponentScan自动扫描组件实例

包扫描会扫描只要标注了@Controller,@Service,@Repository,@Component这四个注解都会被扫描到容器中。

1、@Controller 控制器(注入服务)

用于标注控制层,相当于struts中的action层

2、@Service 服务(注入dao)

用于标注服务层,主要用来进行业务的逻辑处理

3、@Repository(实现dao访问)

用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件.

4、@Component (把普通pojo实例化到spring容器中,相当于配置文件中的 )

泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@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 {



}



新建一个数据库连接Dao类:TestDao



import org.springframework.stereotype.Repository;



@Repository

public class TestDao {



}



新建一个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

https://blog.csdn.net/m0_37739193/article/details/85097477

分享到:
评论

相关推荐

    springboot @ComponentScan注解原理解析

    springboot @ComponentScan注解原理解析 @ComponentScan注解是Spring Boot框架中的一种重要注解,它主要用于扫描Bean并将其注册到Spring容器中。在本文中,我们将深入探讨@ComponentScan注解的原理和应用。 @...

    spring boot 整合mybatis,基于@Select注解方式

    而MyBatis作为一款优秀的持久层框架,以其灵活的SQL映射和对象关系映射能力,深受开发者喜爱。本教程将详细介绍如何在Spring Boot项目中整合MyBatis,并使用@Select注解来实现数据库查询。 首先,我们需要在Spring ...

    springboot中@Async默认线程池导致OOM问题

    在 SpringBoot 中使用 @Async 注解来实现异步操作是一种非常常见的做法,但是如果不小心,可能会导致 OOM(Out of Memory)问题。本文将详细介绍 SpringBoot 中 @Async 默认线程池导致 OOM 问题的原因、解决方法以及...

    Springboot中@Value的使用详解

    "Springboot中@Value的使用详解" @Value是Spring框架中的一个重要注解,用于将配置文件中的属性...在Springboot中,我们可以使用@Value注解来实现各种类型的属性注入,例如字符串、基本类型、数组、List和Map类型。

    springboot使用@data注解减少不必要代码

    @Data 注解是 Lombok 库提供的一种注解,它可以自动为 Java 类生成 setter 和 getter 方法,从而减少不必要的代码。使用 @Data 注解,可以使我们的代码更加简洁和易维护。 二、如何使用 @Data 注解? 要使用 @Data...

    SpringBoot的filter过滤器(源代码)

    2.1.1 启动类增加注解@ServletComponentScan 2.1.2 定义一个filter类 2.1.3. 测试 2.2 第二种方式 2.2.1 自定义fitler类 2.2.4 在启动类中进行配置 2.4.3 第二种方式的另一种写法 2.4.4. 测试 2.3 过滤器的小案例 ...

    Spring Boot中的@ComponentScan注解:深入理解组件扫描机制

    Spring Boot是一个开源的Java框架,用于创建独立、微服务的...本文通过深入分析@ComponentScan注解的工作原理和使用场景,为读者提供了一个全面的指南,帮助他们在Spring Boot应用程序开发中有效地利用组件扫描功能。

    springboot @WebFilter注解过滤器的实现

    SpringBoot 框架提供了多种方式来实现过滤器,例如使用 Servlet Filter API 或者使用 Spring 的 HandlerInterceptor机制,但是 SpringBoot 2.x 版本中引入了新的 @WebFilter 注解,提供了更加简洁和灵活的方式来实现...

    如何在Spring Boot中使用@AfterReturning注解

    通过遵循这些最佳实践,你可以有效地利用 Spring Boot AOP 中的@AfterReturning 注解,实现代码的模块化和可维护性,提高开发效率。记住,AOP 的核心理念是将关注点分离,从而简化应用程序的架构和维护工作。

    springboot通过@Condition注解类型完成加载配置内容

    通过@Bean和@Condition 注解自定义对于的condition里面根据自定义的条件实现指定类注入到spring中;@ConditionalOnProperty可以根据配置文件中的 属性值不同将不同的类注入到spring中 该资源中案例完整,代码简单移动

    SpringBoot @ConfigurationProperties使用详解(源代码)

    在Spring Boot中注解@ConfigurationProperties有三种使用场景,而通常情况下我们使用的最多的只是其中的一种场景。本篇文章带大家了解一下三种场景的使用情况。 1.2 场景一 使用@ConfigurationProperties和@...

    [[springBoot系列]--springBoot注解大全].md

    [[springBoot系列]--springBoot注解大全]

    SpringBoot 、Shiro、 自定义注解权限控制源码下载

    3. **Shiro的集成**:研究如何在SpringBoot应用中配置Shiro,包括安全配置、 Realm(认证和授权信息提供者)的实现以及自定义注解的编写和使用。 4. **Shiro的权限控制**:掌握如何使用Shiro的注解进行权限判断,如@...

    Eclipse-SpringBoot框架-注解介绍.docx

    在Spring Boot应用中,`@SpringBootApplication`是一个复合注解,它包含`@EnableAutoConfiguration`和`@ComponentScan`。`@EnableAutoConfiguration`使得Spring Boot能够自动配置应用,而`@ComponentScan`则用于扫描...

    在springboot中使用注解将值注入参数的操作

    Spring Boot 框架提供了强大的注解机制,允许开发者使用注解将值注入参数,从而简化代码编写和维护。本文将介绍如何在 Spring Boot 中使用注解将值注入参数,主要涵盖了定义注解、定义注解处理类、使 Spring Boot ...

    SpringBoot注解文档

    1. `@SpringBootApplication`: 这是Spring Boot的核心注解,结合了`@SpringBootConfiguration`、`@EnableAutoConfiguration`和`@ComponentScan`三个注解的功能。它告诉Spring Boot如何启动应用程序,自动配置相关...

    SpringBoot 注解

    SpringBoot 注解大全,满足一般的Java需求开发,自己做的一个注解chm文档

    springboot常用注解

    @SpringBootApplication 注解是一个复合注解,包括了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解的功能。它表示当前类是 SpringBoot 应用程序的启动类,并且启用了自动配置和组件扫描。 ...

    浅谈springBoot注解大全

    @SpringBootApplication 注解是 Spring Boot 的核心注解,包含了 @ComponentScan、@Configuration 和 @EnableAutoConfiguration 三个注解。其中,@ComponentScan 让 Spring Boot 扫描到 Configuration 类并把它加入...

    [springBoot系列]-springBoot注解大全.pdf

    这是SpringBoot的入口注解,它包含`@ComponentScan`, `@Configuration`和`@EnableAutoConfiguration`。`@ComponentScan`会扫描指定包及其子包下的所有@Component类型的类,将它们加入到Spring应用上下文中。`@...

Global site tag (gtag.js) - Google Analytics