进阶注解探秘:深入Spring高级注解的精髓与实际运用

简介: 进阶注解探秘:深入Spring高级注解的精髓与实际运用


@Configuration

@Configuration 注解是一个类级别的注解,也是 @Component 的衍生注解,它指示 Spring 容器该类是一个配置类并且应该被处理以生成 Bean 定义和服务请求。@Configuration 注解告诉 Spring 容器这个类是一个 Bean 配置文件,其中可能包含了多个 Bean 的定义。

通过 @Configuration 注解,我们就可以完全替换掉 XML 配置的方式。

需要注意的是,在原来的测试类中,创建 Spring 工厂使用的是 ClassPathXmlApplicationContext,当我们想要使用 @Configuration 配置 Bean 来创建工厂时,我们需要使用 AnnotationConfigApplicationContext。在使用这个类的时候,我们可以直接传入配置 Bean 的 Class,也可以指定一个包路径。

创建配置类

package world.xuewei.config;
import org.springframework.context.annotation.Configuration;
/**
 * Spring 配置 Bean
 *
 * @author 薛伟
 * @since 2023/10/27 14:42
 */
@Configuration
public class AppConfig {
}

创建测试类

package world.xuewei;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import world.xuewei.config.AppConfig;
/**
 * 配置 Bean 测试
 *
 * @author 薛伟
 * @since 2023/10/26 10:17
 */
public class ConfigurationTest {
    private ApplicationContext context;
    @Before
    public void before() {
        // 指定配置类的 Class,创建 Spring 工厂
        context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 指定配置类所在的包路径,配置 Bean 需要在此包或者子包下
        context = new AnnotationConfigApplicationContext("world.xuewei");
    }
    @Test
    public void test1() {
    }
}

@Bean

在 Spring 框架中,@Bean 注解用于将方法标记为 Bean 定义提供程序。通过在 @Configuration 注解的类中使用 @Bean 注解,您可以告诉 Spring 容器该方法将返回一个对象,该对象应该被注册为 Spring 上下文中的 Bean。

@Bean 注解有以下特点和用途:

  1. 方法级别的注解:@Bean 注解是一个方法级别的注解,它通常用于 @Configuration 注解的类中的方法上。
  2. Bean 定义:当使用 @Bean 注解标记一个方法时,该方法的返回值将被注册为一个 Spring Bean。Spring 容器将根据方法返回的对象类型自动创建 Bean,并将其添加到应用程序上下文中。
  3. 自定义 Bean 名称:默认情况下,Bean 的名称与带有 @Bean 注解的方法名称相同。您可以通过在 @Bean 注解中指定 name 属性来自定义 Bean 的名称。
  4. 依赖注入:@Bean 注解还可以处理依赖注入。如果 @Bean 方法需要其他 Bean 作为参数,Spring 容器将自动解析并注入这些依赖项。
  5. 单例作用域:默认情况下,通过 @Bean 注解注册的 Bean 是单例的。这意味着每次从 Spring 容器获取该 Bean 时,都会返回同一个实例。可以搭配 @Scope 注解改变对象的作用域。
  6. 配置外部库:@Bean 注解非常适合用于配置第三方库或外部组件,您可以将其实例化并注册为 Spring Bean,以便在应用程序中使用。

注意:当 @Bean 标记在一个方法上的时候,这个方法必须是 public 的。返回值就是 Bean 的类型,方法名默认就是 Bean 的 id。如果有参数,那么参数会自动的注入。

示例 Demo

package world.xuewei.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import world.xuewei.dao.AccountDao;
import world.xuewei.entity.Account;
import world.xuewei.service.AccountService;
import world.xuewei.service.AccountServiceImpl;
import java.sql.Connection;
import java.sql.DriverManager;
/**
 * Spring 配置 Bean
 *
 * @author 薛伟
 * @since 2023/10/27 14:42
 */
@Configuration
@PropertySource("classpath:db.properties")
public class AppConfig {
    /**
     * 连接驱动
     */
    @Value("${jdbc.driveName}")
    private String driveName;
    /**
     * 连接地址
     */
    @Value("${jdbc.url}")
    private String url;
    /**
     * 用户名
     */
    @Value("${jdbc.username}")
    private String username;
    /**
     * 密码
     */
    @Value("${jdbc.password}")
    private String password;
    /**
     * 创建一个 id 为默认方法名 account 的 Bean
     */
    @Bean
    public Account account() {
        return new Account(1, "xw", "123456");
    }
    /**
     * 创建一个 id 为 acc 的 Bean,并且为多实例
     */
    @Bean(name = "acc")
    @Scope("prototype")
    public Account account1() {
        return new Account(1, "xw", "123456");
    }
    /**
     * 创建复杂对象 Bean
     */
    @Bean
    public Connection connection() {
        Connection connection = null;
        try {
            Class.forName(driveName);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return connection;
    }
    @Bean
    public AccountDao accountDao() {
        return new AccountDao();
    }
    /**
     * 创建 AccountService Bean
     *
     * @param accountDao 自动注入 AccountDao
     */
    @Bean
    public AccountService accountService(AccountDao accountDao) {
        AccountServiceImpl accountService = new AccountServiceImpl();
        accountService.setAccountDao(accountDao);
        return accountService;
    }
}

@ComponentScan

@ComponentScan 注解是 Spring 提供的一种基于注解的配置方式,它可以在 Java 类上直接使用,也可以在配置类上使用。

@ComponentScan 注解包含几个重要的属性:basePackagesexcludeFiltersincludeFiltersuseDefaultFilters。作用和上述 XML 方式一样。

@ComponentScan(basePackages = "world.xuewei", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Account.class),
        @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class),
        @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test"),
        @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "world.xuewei.dao..*"),
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyCustomFilter.class),
})
@Component
public class AnnotationTest {
  // ...
}

具体配置内容可查看前面整理的《Spring注解扫描》

@Import

在 Spring 框架中,@Import 注解用于将其他配置类导入当前配置类中。通过使用 @Import 注解,您可以将其他配置类中的 Bean 定义引入到当前配置类中,从而实现 Bean 的组合和重用。

@Import 注解有以下特点和用途:

  1. 导入其他配置类:@Import 注解允许您将其他配置类导入到当前配置类中。这意味着您可以将其他配置类中定义的 Bean 引入到当前配置类中,并将其注册为 Spring 上下文中的 Bean。
  2. 组合和重用 Bean:通过 @Import 注解,您可以将多个配置类中定义的 Bean 组合在一起,以创建更复杂的应用程序上下文。这使得 Bean 的重用和组合变得更加容易。
  3. 多态性:@Import 注解支持多态性,这意味着您可以使用父类或接口类型来引用导入的 Bean。这使得应用程序更加灵活和易于扩展。
  4. 条件导入:@Import 注解还支持条件导入,这意味着您可以根据特定条件选择性地导入配置类。例如,您可以根据运行时环境的不同导入不同的配置类。

配置类的引入

@Configuration
public class AppConfig1 {
    // 配置类1的内容
}
@Configuration
public class AppConfig2 {
    // 配置类2的内容
}
@Configuration
@Import({AppConfig1.class, AppConfig2.class})
public class MainConfig {
    // 主配置类的内容
}

普通类的引入

@Configuration
@Import({UtilClass1.class, UtilClass2.class, ...})
public class AppConfig {
    // 配置类的内容
}

@Import 注解导入了多个普通类,这些类将被自动注册为 Spring 容器中的 Bean,可以在其他组件中进行依赖注入或使用。

@ImportResource

@ImportResource 注解是 Spring 框架中的一个注解,用于在配置类中引入 XML 配置文件。通过 @ImportResource 注解,我们可以将 XML 配置文件中定义的 bean 引入到当前的配置类中,从而实现 XML 配置文件与 Java 配置类的混合使用。

@Configuration
@ImportResource("classpath:example.xml")
public class AppConfig {
    // 配置类的内容
}
@Configuration
@ImportResource({"classpath:example1.xml", "classpath:example2.xml"})
public class AppConfig {
    // 配置类的内容
}

注意:@ImportResource 注解只能用于 @Configuration 注解标记的配置类中。


相关文章
|
6月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
941 128
|
6月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
659 0
|
5月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
602 2
|
6月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
746 1
使用Spring的@Retryable注解进行自动重试
|
6月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
439 12
|
6月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
334 0
探索Spring Boot的@Conditional注解的上下文配置
|
6月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
255 0
Spring中最大化@Lazy注解,实现资源高效利用
|
6月前
|
安全 IDE Java
Spring 的@FieldDefaults和@Data:Lombok 注解以实现更简洁的代码
本文介绍了如何在 Spring 应用程序中使用 Project Lombok 的 `@Data` 和 `@FieldDefaults` 注解来减少样板代码,提升代码可读性和可维护性,并探讨了其适用场景与限制。
225 0
Spring 的@FieldDefaults和@Data:Lombok 注解以实现更简洁的代码
|
6月前
|
Java 测试技术 编译器
@GrpcService使用注解在 Spring Boot 中开始使用 gRPC
本文介绍了如何在Spring Boot应用中集成gRPC框架,使用`@GrpcService`注解实现高效、可扩展的服务间通信。内容涵盖gRPC与Protocol Buffers的原理、环境配置、服务定义与实现、测试方法等,帮助开发者快速构建高性能的微服务系统。
1196 0
|
6月前
|
XML Java 测试技术
使用 Spring 的 @Import 和 @ImportResource 注解构建模块化应用程序
本文介绍了Spring框架中的两个重要注解`@Import`和`@ImportResource`,它们在模块化开发中起着关键作用。文章详细分析了这两个注解的功能、使用场景及最佳实践,帮助开发者构建更清晰、可维护和可扩展的Java应用程序。
318 0

热门文章

最新文章