一文掌握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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听