SpringBoot(五)之新增注解

简介: 用于 Spring MVC 测试,仅加载 Web 层。

Spring Boot 提供了许多注解来简化开发过程,增强配置能力和提高生产力。以下是一些常用的 Spring Boot 注解及其用途:


核心注解

@EnableAutoConfiguration

@EnableAutoConfiguration 是 Spring Boot 中的一个核心注解,它的主要作用是启用 Spring Boot 的自动配置机制。这个注解告诉 Spring Boot 基于应用程序的类路径设置、其他 bean 和各种属性设置来自动配置 Spring 应用上下文。


详细作用


自动配置 Bean:根据项目依赖的库自动配置相应的 Spring Bean。例如,如果项目依赖中包含 spring-boot-starter-web,@EnableAutoConfiguration 会自动配置 Spring MVC 相关的 bean。

简化配置:通过自动配置,开发者不再需要手动编写大量的配置类,只需要少量的自定义配置即可实现复杂的功能。

条件配置:自动配置是有条件的,依赖于特定的条件注解(如 @ConditionalOnClass、@ConditionalOnMissingBean 等),只有在满足这些条件时才会生效。例如,只有在类路径中存在 DataSource 类时,才会配置数据源相关的 bean。

配置覆盖:开发者可以通过在应用中定义相同类型的 bean 来覆盖自动配置的 bean,从而实现自定义的行为。

使用方法


通常情况下,不需要直接使用 @EnableAutoConfiguration,而是通过 @SpringBootApplication 间接启用。@SpringBootApplication 是一个组合注解,包括 @EnableAutoConfiguration、@ComponentScan 和 @Configuration。


@SpringBootApplication

组合注解,包括 @Configuration、@EnableAutoConfiguration 和 @ComponentScan。

用于标注主配置类,启用自动配置和组件扫描。


@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@SpringBootApplication标识的类作为SpringApplication.run的参数运行,SpringApplication.run()方法在运行时,会创建Spring容器,这时@SpringBootApplication由于包含@Configuration注解,所以该类作为配置类给Spring,


Spring在创建容器的时候,解析该类上的所有注解,包括


@EnableAutoConfiguration,开启SpringBoot的自动配置功能,自动配置功能用于扫描SpringBoot组件的相关配置的SpringBean,并自动装载这些Bean。


@ComponentScan,用于扫描本身项目中(自己当前写的项目)需要扫描的Bean的包路径,默认为@SpringBootApplication标注的类的当前包以及子包。


在SpringBootConfigApplication同级目录下创建TestApplication


public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestMainConfig.class,args);
    }
}

在config目录下创建TestMainConfig

@SpringBootApplication(scanBasePackages = "cn.axj.springbootstart")
public class TestMainConfig {
}

项目结构如下:




打开TestApplication,并运行main方法,项目正常运行。


                    .__                  __
_____    _______  __|__|____    ____    |__|__ __  ____
\__  \  /  _ \  \/  /  \__  \  /  _ \   |  |  |  \/    \
 / __ \(  <_> >    <|  |/ __ \(  <_> )  |  |  |  /   |  \
(____  /\____/__/\_ \__(____  /\____/\__|  |____/|___|  /
     \/            \/       \/      \______|          \/


    :: spring boot config ::                (2.0)
       spring-boot-config-test

2024-05-17 10:19:28.709  INFO 12896 --- [           main] cn.axj.springbootstart.TestApplication   : Starting TestApplication using Java 1.8.0_261 on DESKTOP-SQBHU59 with PID 12896 (D:\practise\spring-all\spring-boot-config\target\classes started by aoxiaojun in D:\practise\spring-all)
2024-05-17 10:19:28.711  INFO 12896 --- [           main] cn.axj.springbootstart.TestApplication   : No active profile set, falling back to 1 default profile: "default"
.....

此时项目中有两个入口,分别是TestApplication和SpringBootAnnotationApplication


将SpringBootAnnotationApplication中的@SpringBootApplication注解去掉,并执行mvn clean package,会看到如下报错



Unable to find a single main class from the following candidates [cn.axj.springbootstart.SpringBootAnnotationApplication, cn.axj.springbootstart.TestApplication]

这是因为打包过程中,发现有两个入口,不知道选用哪个。


条件注解


Spring原生Conditional注解


Spring中有一个功能,可以根据条件来决定一个类型的Bean是否作为候选组件加入到容器中,所以Spring定义了一个注解**@Conditional**,用来在定义Bean的时候给他上条件,根据条件来判断是否加入到Spring容器中。 @Conditional注解如下



public @interface Conditional {
    Class<? extends Condition>[] value();
}

内部有一个Class属性需要继承自Condition。Condition如下

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
手写Conditional注解


现在来手写实现一个自己的@MyConditionalOnClass注解功能


  1. 定义@MyConditionalOnClass的条件判断类MyConditionOnClass
public class MyConditionOnClass implements Condition {
    
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyConditionalOnClass.class.getName());
        String clazz = (String) annotationAttributes.get("value");
        try {
            //尝试加载该类,如果能正常加载,则条件返回true,不能则返回false
            Class.forName(clazz);
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
  1. 定义@MyConditionalOnClass
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({MyConditionOnClass.class})
public @interface MyConditionalOnClass {
    String value();
}
  1. 测试


  • 创建空Bean类MyBean
public class MyBean {
}
  • 创建空条件类ConditionBean
public class ConditionBean {
}
  • 创建配置类BeanConfiguration,并尝试注入MyBean,加上@MyConditionalOnClass条件注解
@Configuration
public class BeanConfiguration {
    @Bean
    @MyConditionalOnClass(value = "cn.axj.springbootstart.config.ConditionBean")
    public MyBean myBean(){
        //如果该Bean被创建了,则打印该信息
        System.out.println("myBean被创建");
        return new MyBean();
    }
}

启动SpringBootAnnotationApplication项目,观察console控制台,可以看到MyBean被创建



将ConditionBean删除,再次启动SpringBootAnnotationApplication项目,观察console控制台,可以观察MyBean没有被创建,条件注解生效。


@ConditionalOnProperty

根据配置属性的存在或值来条件性地配置 bean。



@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class MyFeatureConfig {
}
@ConditionalOnMissingBean
  • 当容器中缺少指定类型的 bean 时,才创建当前 bean。
@ConditionalOnMissingBean(MyService.class)
@Bean
public MyService myService() {
    return new MyService();
}

多个同类型的bean,只需要注入一个的时候,可以将所有的Bean都定义并配置,所有的Bean均加上@ConditionOnMissingBean注解,这样Spring容器在加载完成一个这个类型的Bean后,后续的就不会再创建。


@ConditionalOnBean

当容器中存在指定类型的 bean 时,才创建当前 bean。



@ConditionalOnBean(MyService.class)
public class MyBeanConfig {
}
@ConditionalOnMissingClass

这个注解用于基于应用程序启动时类路径中的特定类的缺失来有条件地启用 Spring bean 或配置类。当您希望在某些依赖项不可用时提供替代配置或实现时,它特别有用。

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.stereotype.Component;

@Component
@ConditionalOnMissingClass("com.example.SomeClass")
public class MyComponent {
    // Bean implementation here
}

在这个示例中,只有在类路径中缺少 SomeClass 时,MyComponent 才会被注册为一个 Spring bean。如果 SomeClass 存在,MyComponent 就不会被注册。


配置和属性注解

@ConfigurationProperties

用于将属性文件中的配置映射到 Java 对象。



@ConfigurationProperties(prefix = "test.some")
public class AppProperties {
    private String name;
    private String description;
    // getters and setters
}

测试注解

@SpringBootTest
  • 用于 Spring Boot 应用的集成测试。
@SpringBootTest
public class MyApplicationTests {
    @Test
    public void contextLoads() {
    }
}

@WebMvcTest


  • 用于 Spring MVC 测试,仅加载 Web 层。

目录
相关文章
|
25天前
|
Java Spring 容器
如何解决spring EL注解@Value获取值为null的问题
本文探讨了在使用Spring框架时,如何避免`@Value(&quot;${xxx.xxx}&quot;)`注解导致值为null的问题。通过具体示例分析了几种常见错误场景,包括类未交给Spring管理、字段被`static`或`final`修饰以及通过`new`而非依赖注入创建对象等,提出了相应的解决方案,并强调了理解框架原理的重要性。
87 4
|
9天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
3月前
|
Java 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
150 1
|
3月前
|
缓存 Java 数据库连接
Spring Boot奇迹时刻:@PostConstruct注解如何成为应用初始化的关键先生?
【8月更文挑战第29天】作为一名Java开发工程师,我一直对Spring Boot的便捷性和灵活性着迷。本文将深入探讨@PostConstruct注解在Spring Boot中的应用场景,展示其在资源加载、数据初始化及第三方库初始化等方面的作用。
77 0
|
21天前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
56 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
14天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
18天前
|
XML Java 数据库
Spring boot的最全注解
Spring boot的最全注解
|
19天前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
19天前
|
Java API Spring
springBoot:注解&封装类&异常类&登录实现类 (八)
本文介绍了Spring Boot项目中的一些关键代码片段,包括使用`@PathVariable`绑定路径参数、创建封装类Result和异常处理类GlobalException、定义常量接口Constants、自定义异常ServiceException以及实现用户登录功能。通过这些代码,展示了如何构建RESTful API,处理请求参数,统一返回结果格式,以及全局异常处理等核心功能。
|
25天前
|
Java Spring 容器
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
这篇文章讨论了在Spring Boot 3.2.1版本中,同名同类型的bean和@Service注解类之间冲突的问题得到了解决,之前版本中同名bean会相互覆盖,但不会在启动时报错,而在配置文件中设置`spring.main.allow-bean-definition-overriding=true`可以解决这个问题。
60 0
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复