@Conditional注解在实际项目中的使用demo演示

一、demo背景

@Conditional注解一般是和Condition接口配合使用的。

在实际项目中,跨平台适配是常见需求(如文件路径、数据库驱动、消息队列等的差异)。本demo通过@Conditional注解,实现根据操作系统类型动态加载不同文件路径服务的功能:Windows系统加载C:\data\路径,Linux系统加载/var/data/路径,避免硬编码带来的维护成本。

二、demo实现步骤

1. 定义业务接口

首先,定义一个通用的FileService接口,声明获取文件路径的方法:

public interface FileService {
    String getFilePath(); // 返回文件存储路径
}

2. 实现不同系统的具体服务

分别实现Windows和Linux系统的文件服务:

// Windows系统实现
public class WindowsFileService implements FileService {
    @Override
    public String getFilePath() {
        return "C:\\data\\"; // Windows路径格式
    }
}

// Linux系统实现
public class LinuxFileService implements FileService {
    @Override
    public String getFilePath() {
        return "/var/data/"; // Linux路径格式
    }
}

3. 自定义Condition类(核心条件判断)

创建两个Condition实现类,用于判断当前操作系统类型:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

// Windows系统条件判断
public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 从环境变量中获取操作系统名称(如"Windows 10"、"Linux")
        String osName = context.getEnvironment().getProperty("os.name");
        boolean flag = osName != null && osName.toLowerCase().contains("windows");
        System.out.println("WindowsCondition matches: " + flag);
        return flag;
    }
}




import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

// Linux系统条件判断
public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String osName = context.getEnvironment().getProperty("os.name");
        boolean flag = osName != null && osName.toLowerCase().contains("linux");
        System.out.println("LinuxCondition matches: " + flag);
        return flag;
    }
}

4. 配置类:绑定条件与Bean

通过@Conditional注解,将FileService的不同实现与操作系统条件绑定:

@Configuration
public class FileServiceConfig {
    // 仅当操作系统为Windows时,加载WindowsFileService
    @Bean
    @Conditional(WindowsCondition.class)
    public FileService windowsFileService() {
        return new WindowsFileService();
    }

    // 仅当操作系统为Linux时,加载LinuxFileService
    @Bean
    @Conditional(LinuxCondition.class)
    public FileService linuxFileService() {
        return new LinuxFileService();
    }
	
	// 未匹配任何条件时(如macOS),加载默认的MacOSFileService
    @Bean
    @ConditionalOnMissingBean(FileService.class)
    public FileService defaultFileService() {
        return new MacOSFileService();
    }
}

5. 测试验证

创建一个简单的控制器,验证不同系统下的路径输出:

@RestController
public class FileController {
    @Autowired
    private FileService fileService; // 自动注入符合条件的Bean

    @GetMapping("/file-path")
    public String getFilePath() {
        return "当前系统文件路径:" + fileService.getFilePath();
    }
}

或者使用:
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    FileService fileService = (FileService)context.getBean(FileService.class);
    System.out.println(fileService.getFilePath());

6. 运行结果

WindowsCondition matches: true
LinuxCondition matches: false
C:\data\
  • Windows系统:启动项目后,访问http://localhost:8080/file-path,返回当前系统文件路径:C:\data
  • Linux系统:访问同一接口,返回当前系统文件路径:/var/data/
  • 其他系统(如macOS):若未匹配任何条件,fileService将为null(可通过@ConditionalOnMissingBean添加默认实现,此处省略)。

三、关键点说明

  1. 条件判断逻辑Condition接口的matches方法通过ConditionContext获取环境变量(os.name),判断操作系统类型;
  2. Bean加载控制@Conditional注解将条件与Bean绑定,只有条件满足时,Bean才会被注册到Spring容器;
  3. 单一Bean保证:由于FileService是接口,且每次只会有一个实现类满足条件,避免了Bean冲突。

四、扩展思考

若需支持更多系统(如macOS),只需新增对应的Condition实现类(如MacCondition)和FileService实现类(如MacFileService),并在配置类中添加对应的@Bean方法即可。这种设计让系统具备良好的扩展性,能适应未来可能的跨平台需求。

posted on 2025-09-25 16:33  ~码铃薯~  阅读(5)  评论(0)    收藏  举报

导航