拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Spring @Component注解

Spring @Component注解

白鹭 - 2021-11-24 1163 0 0

1.概述

在本教程中,我们将全面介绍Spring @Component批注和相关区域。到最后,我们将看到使用它与某些Spring核心功能集成的不同方法,以及如何利用其许多优点。

2. Spring ApplicationContext

在我们了解@Component的值之前,我们必须首先了解一些有关Spring ApplicationContext 。在这里,Spring会保存已确定要自动管理和分发的对象的实例。这些被称为豆。 Bean管理和依赖注入的机会是Spring的一些主要功能。

使用“控制反转”原理, Spring从我们的应用程序中收集bean实例,并在适当的时间使用它们。我们可以显示对Spring的bean依赖关系,而无需处理那些对象的设置和实例化。

使用@Autowired注释将Spring托管的bean注入我们的应用程序的能力是在Spring中创建功能强大且可伸缩的代码的驱动力。

那么,我们如何告诉Spring我们希望它为我们管理的bean?我们应该通过在类上使用构造型注释来利用Spring的自动bean检测功能。

3. @Component

@Component是一个注释,它允许Spring自动检测我们的自定义bean。

换句话说,无需编写任何显式代码,Spring即可:

  • 扫描我们的应用程序以查找带有@Component
  • 实例化它们并将任何指定的依赖项注入到它们中
  • 随时随地注入

但是,大多数开发人员更喜欢使用更专业的构造型注释来实现此功能。

3.1。Spring 其他注解

Spring提供了一些专门的@Controller@Service Service和@Repository 。它们都提供与@Component相同的功能。它们都具有相同作用的原因是它们都是由@Component作为每个注释的元注释组成的注释。它们就像@Component别名,具有特殊用途,并且在Spring自动检测或依赖项注入之外具有含义。

如果确实需要,从理论上讲,我们可以选择@Component来满足我们的bean自动检测需求。另一方面,我们也可以使用@Component自己的专用注释。但是,Spring的其他领域专门针对Spring的特殊注释,以提供额外的自动化好处。因此,我们可能大多数时候都应该坚持使用已建立的专业。

假设我们在Spring Boot项目中有每种情况的示例:

@Controller

 public class ControllerExample {

 }



 @Service

 public class ServiceExample {

 }



 @Repository

 public class RepositoryExample {

 }



 @Component

 public class ComponentExample {

 }



 @Target({ElementType.TYPE})

 @Retention(RetentionPolicy.RUNTIME)

 @Component

 public @interface CustomComponent {

 }



 @CustomComponent

 public class CustomComponentExample {

 }

我们可以编写一个测试来证明Spring会自动检测到每个测试并将其添加到ApplicationContext

@SpringBootTest

 @ExtendWith(SpringExtension.class)

 public class ComponentUnitTest {



 @Autowired

 private ApplicationContext applicationContext;



 @Test

 public void givenInScopeComponents_whenSearchingInApplicationContext_thenFindThem() {

 assertNotNull(applicationContext.getBean(ControllerExample.class));

 assertNotNull(applicationContext.getBean(ServiceExample.class));

 assertNotNull(applicationContext.getBean(RepositoryExample.class));

 assertNotNull(applicationContext.getBean(ComponentExample.class));

 assertNotNull(applicationContext.getBean(CustomComponentExample.class));

 }

 }

3.2。 @ComponentScan

在我们完全依赖@Component之前,我们必须了解一下,它本身只是一个简单的注释。注释用于将bean与其他对象(例如域对象)区分开的目的。但是, Spring使用@ComponentScan批注将它们全部收集到其ApplicationContext

如果我们正在编写Spring Boot应用程序,那么了解@SpringBootApplication是一个包含@ComponentScan的组合批注会很有帮助。只要我们的@SpringBootApplication类位于项目的根目录下,它将扫描默认情况下定义的@Component

但是,如果我们的@SpringBootApplication类不能位于项目的根目录下,或者我们想扫描外部源,则可以@ComponentScan以查找我们指定的任何包,只要它存在于类路径中即可。

让我们定义一个范围外的@Component bean:

package com.baeldung.component.scannedscope;



 @Component

 public class ScannedScopeExample {

 }

接下来,我们可以通过对@ComponentScan批注的明确说明将其包括在内:

package com.baeldung.component.inscope;



 @SpringBootApplication

 @ComponentScan({"com.baeldung.component.inscope", "com.baeldung.component.scannedscope"})

 public class ComponentApplication {

 //public static void main(String[] args) {...}

 }

最后,我们可以测试它的存在:

@Test

 public void givenScannedScopeComponent_whenSearchingInApplicationContext_thenFindIt() {

 assertNotNull(applicationContext.getBean(ScannedScopeExample.class));

 }

实际上,当我们要扫描项目中包含的外部依赖项时,更可能发生这种情况。

3.3。 @Component限制

@Component时,我们希望某个对象成为Spring管理的bean。

例如,让我们在项目外部的包中@Component

package com.baeldung.component.outsidescope;



 @Component

 public class OutsideScopeExample {

 }

这是一个证明ApplicationContext不包含外部组件的测试:

@Test

 public void givenOutsideScopeComponent_whenSearchingInApplicationContext_thenFail() {

 assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(OutsideScopeExample.class));

 }

另外,我们可能无法访问源代码,因为它来自第三方资源,并且我们无法添加@Component批注。或者,也许我们想根据我们所运行的环境有条件地使用一种bean实现,而不是另一种。大多数情况下,自动检测就足够了,但是如果不是,我们可以使用@Bean

4. @Component@Bean

@Bean也是Spring在运行时用于收集bean的注释,但在类级别未使用。相反,我们使用@Bean注释方法,以便Spring可以将方法的结果存储为Spring Bean。

要查看其工作方式的示例,首先让我们创建一个没有注释的POJO:

public class BeanExample {

 }

@Configuration注释的类中,我们可以创建一个bean生成方法:

@Bean

 public BeanExample beanExample() {

 return new BeanExample();

 }

BeanExample可能表示一个本地类,也可能是一个外部类。没关系,因为我们只需要返回它的一个实例。

然后,我们可以编写一个测试来验证Spring是否确实拾取了bean:

@Test

 public void givenBeanComponent_whenSearchingInApplicationContext_thenFindIt() {

 assertNotNull(applicationContext.getBean(BeanExample.class));

 }

@Component@Bean之间的差异,我们应该注意一些重要的含义。

  • @Component是类级别的注释,但是@Bean是方法级别的,因此@Component仅在类的源代码可编辑时才是一个选项。 @Bean总是可以使用,但是更冗长。
  • @Component与Spring的自动检测兼容,但是@Bean需要手动的类实例化。
  • 使用@Bean将Bean的实例与其类定义解耦。这就是为什么我们可以使用它甚至将3rd Party类制作为Spring Bean的原因。这也意味着我们可以引入逻辑来决定要使用bean的几个可能的实例选项中的哪一个。

5.结论

我们刚刚探讨了Spring @Component批注以及其他相关主题。首先,我们讨论了各种Spring构造型注解,它们只是@Component专门版本。然后,我们了解到@Component不会执行任何操作,除非@ComponentScan可以找到它。最后,由于无法@Component上使用@Component,因此我们学习了如何使用@Bean注解。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *