spring 实用小技巧

1. @PropertySource注解

加载properties文件,加载完成之后,放到了环境变量Environment当中,通过Environment对象可以直接获取 代码如下所示:

定义一个my.properties文件,写入两个属性:

properties 复制代码
my.app.name=rj
my.app.version=1.0.0

在启动类上添加注解@PropertySource, 引入my.properties文件

java 复制代码
// 读取my.properties这个配置文件
@PropertySource("classpath:my.properties")

测试读取配置文件里的内容

java 复制代码
@Autowired
private Environment environment;

@Test
public void propertyTest(){
    // 读取配置文件
    String name = environment.getProperty("my.app.name");
    // 读取配置文件
    String property = environment.getProperty("my.app.version");
    log.info("name:{},property:{}",name,property);
}

2.@Order注解

在 Spring 中,@Order注解用于定义 Bean 的加载顺序或者特定组件在执行顺序中的优先级。主要作用如下所示

  • 控制 Bean 的初始化顺序

    • 当多个 Bean 需要按照特定的顺序进行初始化时,可以使用@Order注解来指定它们的加载顺序。具有较小值的@Order注解的 Bean 会先被初始化。
    • 例如,在一个复杂的应用中,某些 Bean 可能依赖于其他 Bean 的初始化完成后才能正确工作,通过设置@Order注解可以确保它们按照正确的顺序被创建。
  • 作用于特定组件的执行顺序

    • 过滤器(Filter)的执行顺序:在 Spring Web 应用中,可以使用@Order注解来控制过滤器的执行顺序。具有较小值的过滤器会先执行。
    • 例如,在一个安全相关的应用中,可能有多个过滤器用于不同的安全检查,通过设置@Order注解可以确保它们按照正确的顺序执行,以提供有效的安全防护。
  • 控制拦截器(Interceptor)的执行顺序

    • 在需要控制加载顺序或执行顺序的类上添加@Order注解,并指定一个整数值作为优先级。
    • 多个@Order注解的比较:当多个类都带有@Order注解时,Spring 会根据注解中的值从小到大进行排序。如果两个类的@Order值相同,则它们的执行顺序是不确定的,除非通过其他方式进行明确的排序。

3. 条件注解ConditionalOnProperty

@ConditionalOnProperty注解用于根据特定的配置属性值来决定是否要将某个 Bean 加载到 Spring 容器中。其主要作用如下所示

  • 条件化 Bean 的加载:
    • 这个注解允许你根据配置文件中的属性值来有条件地创建和注册 Bean。如果配置属性满足特定的条件,那么对应的 Bean 就会被加载到 Spring 容器中;否则,该 Bean 将不会被创建。
    • 这在需要根据不同的环境或配置来动态加载特定组件的场景中非常有用。
  • 灵活的配置控制:
    • 通过在配置属性文件中设置不同的值,可以轻松地控制哪些组件在特定的环境中被加载。例如,可以根据开发环境、测试环境或生产环境的不同需求,选择性地加载特定的 Bean。

核心属性:

  • name:指定要检查的配置属性的名称。
  • havingValue:指定当配置属性具有这个值时,条件成立。
  • matchIfMissing:当配置属性不存在时,是否默认条件成立。默认为false,即如果配置属性不存在,条件不成立。测试代码如下所示
java 复制代码
@Service
@ConditionalOnProperty(name = "special.service.enabled", havingValue = "true")
public class SpecialService {

    public void doSpecialThing() {
        System.out.println("SpecialService is working.");
    }
}

在配置文件当中进行配置

yaml 复制代码
special:
  service:
    enabled: false

创建单元测试,根据enable值的不同, 查看一下bean是否已经创建

4. @ImportResource注解

在 SpringBoot 工程中,可以通过 @ImportResource@PropertySource 引入对应的配置文件,完成对象的初始化。

应用场景:

在实际的开发中,虽然使用 SpringBoot 工程,但为了兼容一些老的项目或者一些还没有升级到 SpringBoot Starter 的组件,则需要单独引入 Spring 配置文件来创建对象。

测试代码如下所示:

新建一个实体类

java 复制代码
@Data
public class User {
    private String username;
    private String gender;;
    private String address;
}

在resources新建一spring 的xml文件, 这里的名字是bean.xml

xml 复制代码
<bean id="user" class="com.rj.entity.User">
   <property name="username" value="rj" />
   <property name="gender" value="男" />
   <property name="address" value="深圳" />
</bean>

在启动类添加注解@ImportResource("classpath:spring/bean.xml")

java 复制代码
@SpringBootApplication
// 读取my.properties这个配置文件
@PropertySource("classpath:my.properties")
// 在spring boot当中加载xml文件
@ImportResource("classpath:spring/bean.xml")
public class RjSpringBootDemo01Application {}

单元测试里测试一下

java 复制代码
@Autowired
 private User user;
  @Test
 public void userTest() {
     log.info("user:{}",user);
 }

测试结果如下所示:

5. @Primary注解

当一个接口,有多个对象需要放到容器的时候,再使用@Resources注入使用的时候,此时会抛出异常. 此时可以使用@Primary注解标记一首选对象, 注入的时候,会先注入首选对象.

定义一个接口

java 复制代码
public interface IUserService {
}

定义两个实现类

java 复制代码
@Service
public class AUserServiceImpl implements IUserService {
}

@Service
public class BUserServiceImpl implements IUserService {
}

单元测试一下

java 复制代码
@Autowired
private IUserService userService;

添加@Primary注解

java 复制代码
@Service
@Primary // 默认情况下,如果存在多个实现类,则使用@Primary注解的实现类
@Order(1) // 初始化优先级,数字越小,越小被加载
public class AUserServiceImpl implements IUserService {
}

单元测试

java 复制代码
@Test
public void userServiceTest() {
    log.info("userService:{}",userService);
}

6. @ConditionalOnMissingBean

检测创建Bean, 免费重复创建Bean. 示例如下所示:

java 复制代码
@ConditionalOnMissingBean
@Bean(name = "account01")
public Account account01(){
    return new Account();
}

@ConditionalOnMissingBean
@Bean(name = "account02")
public Account account02(){
    return new Account();
}

测试代码

java 复制代码
@Resource
private Account account;

@Test
public void accountTest() {
  log.info("account:{}",account);
}
相关推荐
秋意钟1 分钟前
Spring新版本
java·后端·spring
椰椰椰耶3 分钟前
【文档搜索引擎】缓冲区优化和索引模块小结
java·spring·搜索引擎
小蜗牛慢慢爬行21 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
Allen Bright28 分钟前
Spring Boot 整合 RabbitMQ:手动 ACK 与 QoS 配置详解
spring boot·rabbitmq·java-rabbitmq
新手小袁_J1 小时前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
goTsHgo1 小时前
在 Spring Boot 的 MVC 框架中 路径匹配的实现 详解
spring boot·后端·mvc
钱多多_qdd1 小时前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
Q_19284999061 小时前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
gb42152872 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端