Spring如何知道在哪里搜索组件或Bean?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring如何知道在哪里搜索组件或Bean?相关的知识,希望对你有一定的参考价值。

[在一次采访中,面试官问我:“ Spring如何知道在哪里搜索组件或Bean?”。由于我不知道内部流程细节,因此无法正确回答问题。我说通过@Component和@Bean我们可以找到。但是,参与者对这个问题并不满意。如果有人知道,请分享您的知识。

答案

在哪里搜索bean是由@ComponentScan定义的,可以在用于引导Spring的@ComponentScan类上进行注释。

例如,它具有一个名为@Configuration的属性,该属性告诉Spring从以下位置扫描bean(用scanBasePackages或其原型(例如@Component@Service@Repository等注解的类)。仅某些软件包及其子软件包。

然后为每个已注册的bean继续检查@Controller是否存在任何方法注释。如果是,还将它们注册为bean。

另一答案

我喜欢回答面试问题。阅读下面...

@Bean

如果您了解组件扫描,您就会了解Spring。

Spring是一个依赖项注入框架。这全都与bean和依赖关系中的接线有关。

定义Spring Bean的第一步是添加正确的注释-@ComponentScan @Component@Service

但是,Spring不知道该bean,除非它知道在哪里搜索它。

“告诉Spring的搜索部分”这一部分称为组件扫描。

您定义必须扫描的软件包。

一旦为包定义了组件扫描,Spring就会在包及其所有子包中搜索组件/ bean。

定义组件扫描

  • 如果使用的是Spring Boot,请检查方法1中的配置。
  • 如果您正在执行JSP / Servlet或Spring MVC应用程序而没有使用Spring Boot,使用方法2。

方法1:Spring Boot项目中的组件扫描

如果其他包层次结构在主应用程序的下方,并带有@Repository批注,则隐式组件扫描将覆盖您。如果其他软件包中的bean /组件不是主软件包的子软件包,则应手动将它们添加为@SpringBootApplication

考虑下课

@ComponentScan

[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); } } } 在包@SpringBootApplication中的SpringbootIn10StepsApplication类中定义”>

[com.in28minutes.springboot.basics.springbootin10steps定义了程序包@SpringBootApplication上的自动组件扫描。

如果您的所有组件都在上面的包或其子包中定义,则很好。

但是,假设其中一个组件是在程序包com.in28minutes.springboot.basics.springbootin10steps中定义的

在这种情况下,您需要将新程序包添加到组件扫描中。

您有两个选择:

选项1:

com.in28minutes.springboot.somethingelse

选项2:

:定义为数组
@ComponentScan(“com.in28minutes.springboot”)
@SpringBootApplication
public class SpringbootIn10StepsApplication {...}

方法2:非春季启动项目

选项1:

@ComponentScan({"com.in28minutes.springboot.basics.springbootin10steps","com.in28minutes.springboot.somethingelse"})
@SpringBootApplication
public class SpringbootIn10StepsApplication {...}

选项2:

@ComponentScan(“com.in28minutes)
@Configuration
public class SpringConfiguration {...}

XML应用程序上下文:

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

特定多个包:

<context:component-scan base-package="com.in28minutes" />
另一答案

IoC(控制反转)容器,在Spring中由类<context:component-scan base-package="com.in28minutes.package1, com.in28minutes.package2" /> 表示,是所有容器的大脑。全部归结为以一种非常强大的方式使用反射。

以上是关于Spring如何知道在哪里搜索组件或Bean?的主要内容,如果未能解决你的问题,请参考以下文章

Spring JSF 集成:如何在 JSF 托管 bean 中注入 Spring 组件/服务?

如何在filter等dubbo自管理组件中注入spring的bean

单元测试在测试spring集成TCP组件时创建名为“amqAdmin”的bean时出错

如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇

spring 组件和 bean 的作用域有啥区别? [复制]

Spring学习系列 通过Java代码装配Bean