一文掌握SpringBoot注解之@Component 知识文集(5)

2024-01-28 10:52

本文主要是介绍一文掌握SpringBoot注解之@Component 知识文集(5),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
🎉欢迎 👍点赞✍评论⭐收藏

🔎 SpringBoot 领域知识 🔎

链接专栏
SpringBoot 专业知识学习一SpringBoot专栏
SpringBoot 专业知识学习二SpringBoot专栏
SpringBoot 专业知识学习三SpringBoot专栏
SpringBoot 专业知识学习四SpringBoot专栏
SpringBoot 专业知识学习五SpringBoot专栏
SpringBoot 专业知识学习六SpringBoot专栏
SpringBoot 专业知识学习七SpringBoot专栏
SpringBoot 专业知识学习八SpringBoot专栏
SpringBoot 专业知识学习九SpringBoot专栏
SpringBoot 专业知识学习十SpringBoot专栏
SpringBoot 专业知识学习十一SpringBoot专栏
SpringBoot 专业知识学习十二SpringBoot专栏
SpringBoot 专业知识学习十三SpringBoot专栏
SpringBoot 专业知识学习十四SpringBoot专栏
SpringBoot 专业知识学习十五SpringBoot专栏
SpringBoot 专业知识学习十六SpringBoot专栏
SpringBoot 专业知识学习十七SpringBoot专栏
SpringBoot 专业知识学习十八SpringBoot专栏
SpringBoot 专业知识学习十九SpringBoot专栏
SpringBoot 专业知识学习二十SpringBoot专栏

文章目录

    • 🔎 Java 注解 @Component 学习(5)
      • 🍁 41、在 Spring 中,如何通过 @Component 注解定义一个切入点(Pointcut)?
      • 🍁 42、@Component 注解的 autowireCandidate 属性的作用是什么?
      • 🍁 43、@Component 注解和 @Import 注解有什么关系?
      • 🍁 44、在 Spring 中,是否可以通过 @Component 注解注入一个原始类型的依赖?
      • 🍁 45、@Component 注解的 primary 属性的作用是什么?
      • 🍁 46、@Component 注解是否支持循环依赖?
      • 🍁 47、在 Spring 中,可以通过 @Component 注解实现动态代理吗?
      • 🍁 48、@Component 注解和 @Qualifier 注解的作用有何区别?
      • 🍁 49、在 Spring 中,是否可以通过 @Component 注解注入一个集合类型的依赖?
      • 🍁 50、@Component 注解的 initMethod 和 destroyMethod 属性的作用是什么?


🔎 Java 注解 @Component 学习(5)

在这里插入图片描述


🍁 41、在 Spring 中,如何通过 @Component 注解定义一个切入点(Pointcut)?

在 Spring 中,定义切入点(Pointcut)是通过 @Pointcut 注解来实现的。而 @Pointcut 注解通常与 @Aspect 注解一起使用,在切面(Aspect)类中定义切入点。

不过,可以通过 @Component 注解来定义一个切面(Aspect)类,并在该类中定义切入点。具体步骤如下:

1.在类上添加 @Component 注解,并使用 @Aspect 注解表示这个类是一个切面类。

@Aspect
@Component
public class MyAspect {//定义切入点和切面方法
}

2.在类中定义一个方法,并使用 @Pointcut 注解来定义切入点。该方法的访问修饰符可以是 publicprivate 等任意访问修饰符,方法体可以为空。

@Aspect
@Component
public class MyAspect {@Pointcut("execution(* com.example.somepackage.*.*(..))")private void myPointcut() {//空方法体,只是为了定义切入点名称}
}

在上述示例中,我们定义了名为 myPointcut 的切入点,它匹配所有 com.example.somepackage 包下的类的所有方法。


🍁 42、@Component 注解的 autowireCandidate 属性的作用是什么?

@Component 注解的 autowireCandidate 属性用于控制 Spring 容器在自动装配时,是否将该 Bean 定义作为自动装配的候选者。

默认情况下,所有标记了 @Component 注解的 Bean 都会作为自动装配的候选者,即如果有其他 Bean 中存在与该 Bean 的依赖类型匹配的 Bean,则该 Bean 将被自动装配。

autowireCandidate 属性可以控制 Bean 是否参与自动装配的候选者的筛选过程,它的取值类型是 boolean,默认值为 true

具体来讲,当 autowireCandidate 属性被设置为 false 时,该 Bean 将不会被自动装配的候选者,即如果有其他 Bean 中存在与该 Bean 的依赖类型匹配的 Bean,也不会自动装配该 Bean。

以下是示例代码:

@Component
public class MyBean {// ... 省略其他属性和方法@Autowired@Qualifier("anotherBean") // 使用 Qualifier 指定注入的 Bean 名称为 "anotherBean"@Value("${some.prop}") // 使用 Value 注入配置属性的值@NonNull // 使用 Lombok 提供的注解标注参数不能为空public MyBean(@NonNull AnotherBean anotherBean, @Value("${some.prop}") String propValue) {// ... 构造方法实现}// ... 省略其他属性和方法
}

在上述代码中,我们使用了 @Autowired 注解来标注构造方法的参数 anotherBean,这告诉 Spring 容器,需要自动装配一个与 AnotherBean 类型相同的 Bean,并使用名为 “anotherBean” 的 Bean。

此外,我们还使用了 @Value 注解来注入一个配置属性的值,并使用了 @NonNull 注解来保障参数的非空性。

需要注意的是,@Autowired 注解具有默认的 required 属性为 true,这意味着如果没有找到与该参数类型匹配的 Bean,或找到的 Bean 的实例数不等于 1,那么 Spring 将会抛出一个异常。如果希望避免出现这种情况,可以将 required 属性设置为 false


🍁 43、@Component 注解和 @Import 注解有什么关系?

@Component 注解和 @Import 注解是 Spring 中两个不同的注解,它们在功能上有一些不同,但也存在一定的关联。

  1. @Component 注解是 Spring 提供的一个通用的注解,用于将一个类标识为一个可管理的组件(Bean),让 Spring 容器自动扫描并将其实例化。@Component 注解通常与 @Autowired@Qualifier@Value 等注解配合使用,用于实现依赖注入、属性注入等功能。

  2. @Import 注解用于手动导入其他的配置类或配置组件(Bean)。通过 @Import 注解可以在配置类中引入其他的配置类,从而将其所定义的 Bean 纳入到当前应用上下文中。同时, @Import 注解可以与 @Configuration 注解一起使用,用于声明该类是一个配置类。

关于两者的关系,可以从以下两个方面来说明:

  • @Import 可以在配置类中引入使用了 @Component 注解的类,将其实例化为 Bean 并纳入到 Spring 容器中。通过这种方式,我们可以在配置类中集中管理所有的 @Component 注解标注的组件。

  • @Import 还可以在配置类中引入其他的配置类,通过组合和导入其他的配置类,我们可以更加灵活地管理和组织项目中的 Bean。

下面是一个示例,展示了 @Component@Import 的关系:

@Configuration
@Import({MyComponent1.class, MyComponent2.class, MyConfig.class})
public class AppConfig {// 配置类的定义
}

在上述示例中,AppConfig 是一个配置类,通过 @Import 注解导入了 MyComponent1MyComponent2MyConfig 这三个类。其中,MyComponent1MyComponent2 可能是使用了 @Component 注解的类,通过 @Import 注解将其纳入到应用上下文中,让 Spring 容器管理它们。


🍁 44、在 Spring 中,是否可以通过 @Component 注解注入一个原始类型的依赖?

在 Spring 中,是不支持通过 @Component 注解直接注入一个原始类型的依赖的,因为原始类型无法作为 Bean 注册到 Spring 容器中,Spring 只会将通过 @Component 注解标注的类作为 Bean 进行管理。

如果需要注入一个原始类型的依赖,可以考虑以下两种方式:

1.通过 @Value 注解注入原始类型的依赖

@Component
public class MyComponent {@Value("${myProp}") // 使用 @Value 注解注入原始类型的依赖private int myProp;// ...
}

在上述示例中,使用 @Value 注解注入了一个原始类型的依赖 myProp,它的值将从 Spring 环境中获取。

2.通过一个 @Configuration 类将原始类型的依赖注入为 Bean

@Configuration
public class MyAppConfig {@Beanpublic int myInt() {return 42; // 返回一个 int 类型的值}
}

在上述示例中,将一个原始类型的依赖 42 注入为一个 Spring Bean myInt,并通过一个 @Configuration 类将其声明为一个配置类,从而引入到 Spring 环境中。

需要注意的是,通过这种方式注入的原始类型依赖不会管理生命周期,因为它们不是标准的 Bean(没有通过 @Component 注解标注),无法交由 Spring 容器管理其生命周期。


🍁 45、@Component 注解的 primary 属性的作用是什么?

在 Spring 中,@Component 注解的 primary 属性用于指定一个 Bean 是否为首选(Primary)的候选者。

当存在多个同类型的 Bean 候选者时,Spring 默认会抛出一个 NoUniqueBeanDefinitionException 异常,表示无法确定要注入哪个 Bean。这种情况下,可以使用 @Primary 注解或 primary 属性来解决这个问题。

具体来说,primary 属性可以被用于 @Component@Service@Repository 等注解。

下面是一个示例:

@Component
@Primary
public class MyComponent1 implements MyInterface {// ...
}@Component
public class MyComponent2 implements MyInterface {// ...
}@Autowired
private MyInterface myInterface;

在上述示例中,有两个实现了 MyInterface 接口的 @Component 注解标注的类:MyComponent1MyComponent2。通过给 MyComponent1 添加 @Primary 注解,我们可以将其指定为首选的 Bean。这样,当进行依赖注入时,如果没有显式指定要注入的 Bean,Spring 将选择 MyComponent1 作为首选的候选者进行注入。

需要注意的是,如果存在多个首选的 Bean,那么与 @Primary 注解相比,primary 属性具有更高的优先级。


🍁 46、@Component 注解是否支持循环依赖?

Spring 框架默认支持通过 @Autowired 进行依赖注入时的循环依赖,但是对于 @Component 注解本身是否支持循环依赖是有一些限制的。

具体来说,在默认情况下,@Component 注解是支持循环依赖的,但是有以下几个限制:

  1. 循环依赖只支持通过构造函数进行依赖注入,不支持通过 Setter 方法进行依赖注入。

  2. 循环依赖需要剥离开发者手动进行处理,即开发者需要通过限制 Bean 的依赖链长度来避免循环依赖导致的死循环和栈溢出等问题。

  3. 循环依赖需要依赖于 Bean 的作用域,如果 Bean 是单例作用域,则可以通过使用 @Lazy 注解或通过使用 ObjectFactoryObjectProviderProvider 等方式进行解决。如果 Bean 是原型作用域,则可以通过使用 @Autowired 注解将依赖注入到方法参数中来解决。

需要注意的是,虽然 Spring 默认支持循环依赖,但是循环依赖会增加程序的复杂度和难度,应该尽量避免。在实际开发中,如果出现了循环依赖的情况,建议优先考虑调整依赖关系,使其不出现循环依赖。


🍁 47、在 Spring 中,可以通过 @Component 注解实现动态代理吗?

在 Spring 中,可以通过 @Component 注解结合其他相关注解,如 @Aspect@EnableAspectJAutoProxy,来实现动态代理。

首先,使用 @Component 注解将目标类(被代理的类)声明为一个 Spring Bean。在目标类的方法上,使用 @Before@After@Around 等注解来定义切面逻辑。同时,需要在配置类上使用 @EnableAspectJAutoProxy 注解启用自动代理功能。

下面是一个示例:

@Aspect
@Component
public class MyAspect {@Before("execution(* com.example.MyClass.myMethod(..))")public void beforeAdvice() {System.out.println("Before advice.");}
}@Component
public class MyClass {public void myMethod() {System.out.println("myMethod");}
}@Configuration
@EnableAspectJAutoProxy
public class AppConfig {// 配置类
}

在上述示例中,MyAspect 类使用了 @Aspect@Component 注解,将其声明为一个切面和 Spring Bean。MyClass 类被标注为 @Component,也成为一个 Spring Bean。MyAspect 类中的 beforeAdvice 方法使用了 @Before 注解,表示在目标方法执行之前执行切面逻辑。

在配置类 AppConfig 上使用了 @EnableAspectJAutoProxy 注解,启用了基于 AspectJ 的自动代理功能。

当 Spring 在运行时扫描到这些注解时,会自动生成一个代理类,用于拦截被 @Aspect 注解标记的切面逻辑,并将其应用到目标类的方法上。

需要注意的是,动态代理是针对接口的,默认情况下 Spring 使用 JDK 动态代理来实现。如果目标类没有实现接口,则 Spring 将使用 CGLIB 动态代理。


🍁 48、@Component 注解和 @Qualifier 注解的作用有何区别?

@Component@Qualifier 是 Spring 框架中常用的注解,具有不同的作用和用途。

@Component 注解是用于定义一个 Bean 实例,被注解的类会被 Spring 容器扫描并创建成一个 Bean。通常,我们使用 @Component 注解来定义 Service、Repository、Controller 等组件类。

@Qualifier 注解是用于指定一个 Bean 实例的名称。当 Spring 容器中存在多个同类型的 Bean 实例时,通过 @Qualifier 注解可以指定使用哪一个 Bean 实例。通常,我们在使用 @Autowired 自动注入时,配合 @Qualifier 注解来指定注入的 Bean 实例。

例如:

@Component
@Qualifier("myService")
public class MyServiceImpl implements MyService {// ...
}@Service
public class BusinessService {@Autowired@Qualifier("myService")private MyService myService;// ...
}

上面的例子中,我们定义了一个 MyServiceImpl 类,并使用 @Qualifier("myService") 注解指定了该 Bean 实例的名称为 “myService”。在 BusinessService 类中,我们使用 @Autowired@Qualifiter("myService") 注解将 myService Bean 自动注入到 myService 字段中。

需要注意的是,@Qualifier 注解只有在 Spring 容器中存在多个同类型的 Bean 实例时才有意义。如果只存在一个同类型的 Bean 实例,不需要使用 @Qualifier 注解。

注解作用使用场景
@Component定义一个 Bean 实例Service、Repository、Controller 等组件类
@Qualifier指定一个 Bean 实例的名称当容器中存在多个同类型的 Bean 实例时,用于指定使用哪一个 Bean 实例

简单来说,@Component 注解用于定义一个 Bean 实例,而 @Qualifier 注解用于指定一个 Bean 实例的名称,用于区分多个同类型的 Bean 实例。


🍁 49、在 Spring 中,是否可以通过 @Component 注解注入一个集合类型的依赖?

在 Spring 中可以通过 @Component 注解来注入一个集合类型的依赖。

Spring 支持将多个相同类型的 Bean 实例注入到一个集合类型的字段或参数中。可以使用 @Autowired 注解结合 @Qualifier 注解来完成这个过程。

下面是一个示例:

@Component
public class MyServiceImpl1 implements MyService {// ...
}@Component
public class MyServiceImpl2 implements MyService {// ...
}@Service
public class BusinessService {@Autowiredprivate List<MyService> myServices;// ...
}

在上面的示例中,我们定义了两个实现了 MyService 接口的类 MyServiceImpl1MyServiceImpl2 并标记为 @Component 注解。接着,在 BusinessService 类中,我们使用 @Autowired 注解并将 List<MyService> 类型的字段 myServices 注入。

这样,Spring 会将所有实现了 MyService 接口的 Bean 实例注入到 myServices 字段中,并以集合的形式提供给我们使用。我们可以在 BusinessService 中遍历或使用集合中的元素。

需要注意的是,如果没有找到任何符合条件的 Bean 实例,集合类型的字段将会是空集合(而不是 null)。


🍁 50、@Component 注解的 initMethod 和 destroyMethod 属性的作用是什么?

@Component 注解的 initMethoddestroyMethod 属性用于指定在 Bean 初始化和销毁时执行的方法。

  • initMethod 属性:用于指定在 Bean 初始化完成后调用的方法。该方法可以进行一些初始化操作,例如数据加载、资源初始化等。需要注意的是,被指定的方法不能有任何参数,且返回类型为 void

  • destroyMethod 属性:用于指定在 Bean 销毁前调用的方法。该方法可以进行一些清理操作,例如资源释放、数据库连接关闭等。需要注意的是,被指定的方法不能有任何参数,且返回类型为 void

示例:

@Component(initMethod = "init", destroyMethod = "cleanup")
public class MyService {public void init() {// 初始化操作}public void cleanup() {// 清理操作}
}

在上面的示例中,我们使用 @Component 注解并通过 initMethoddestroyMethod 属性分别指定了 initcleanup 方法作为 Bean 的初始化方法和销毁方法。在 Spring 容器启动时,会先调用 init 方法进行初始化,当容器关闭时,会调用 cleanup 方法进行清理。

需要注意的是,initMethoddestroyMethod 属性只对 singleton 作用域的 Bean 起作用。对于 prototype 作用域的 Bean,则不会调用销毁方法。

另外,还可以使用 @PostConstruct@PreDestroy 注解来代替 initMethoddestroyMethod 属性,它们也具有相同的作用。

在这里插入图片描述

这篇关于一文掌握SpringBoot注解之@Component 知识文集(5)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653429

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2