Spring 第三方资源配置管理

1 阅读2分钟

日常开发中,MyBatis、Druid、Redis、RabbitMQ、MongoDB、MQ 等都属于第三方组件,Spring IOC 统一接管它们的数据源 / 客户端对象,统一配置、统一生命周期管理,核心分三种方案:XML、JavaConfig、SpringBoot 自动配置。

一、核心思路

第三方组件不会加 @Component,无法自动扫描,需要手动将第三方类注册为 Bean:

  1. 读取外部配置(jdbc.properties/application.yml)
  2. 通过工厂类 / 构造器创建第三方对象
  3. 交给 IOC 容器管理,业务代码直接 @Autowired 注入使用

二、传统 XML 方式(SSM 老项目)

1. 引入外部属性文件

<!-- 加载外部jdbc配置 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456

2. 配置 Druid 数据源(第三方连接池)

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <!-- 连接池参数 -->
    <property name="maxActive" value="20"/>
</bean>

3. MyBatis SqlSessionFactory(第三方工厂 Bean)

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注入上面的数据源Bean -->
    <property name="dataSource" ref="dataSource"/>
    <!-- 映射文件路径 -->
    <property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>

<!-- Mapper扫描,自动生成Dao代理对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.mapper"/>
</bean>

三、JavaConfig 注解方式(Spring 标准,无 XML)

1. @PropertySource 加载外部配置文件

@Configuration
// 加载外部properties
@PropertySource("classpath:jdbc.properties")
// 开启属性占位符解析 ${key}
@ComponentScan("com")
public class SpringConfig {

    // 注入配置文件属性
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    // 第三方Druid数据源注册为Bean
    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setMaxActive(20);
        return ds;
    }

    // MyBatis 第三方工厂Bean
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DruidDataSource dataSource) {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/*.xml"));
        return factory;
    }

    // Mapper扫描器
    @Bean
    public MapperScannerConfigurer mapperScanner() {
        MapperScannerConfigurer scanner = new MapperScannerConfigurer();
        scanner.setBasePackage("com.mapper");
        return scanner;
    }
}

2. @ConfigurationProperties 批量绑定(推荐,批量注入配置)

yml /properties 批量映射实体类,不用逐个写 @Value

@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {

    // 前缀匹配 jdbc.* 批量注入属性
    @Bean
    @ConfigurationProperties(prefix = "jdbc")
    public DruidDataSource dataSource() {
        return new DruidDataSource();
    }
}

四、SpringBoot 第三方自动配置(主流开发方式)

核心原理:SPI + @EnableAutoConfiguration + Conditional

  1. META-INF/spring.factories 定义第三方自动配置类
  2. @ConditionalOnClass:类路径存在第三方依赖才生效
  3. @ConditionalOnMissingBean:用户没自定义 Bean 才创建默认第三方对象
  4. xxxProperties 绑定 application.yml 配置

示例 1:Druid + MyBatis 自动配置

pom 引入第三方 starter

<!-- 数据库连接池druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.20</version>
</dependency>
<!-- mybatis整合springboot -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>

application.yml 配置第三方资源

spring:
  # 数据源第三方配置
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test
      username: root
      password: 123456
      max-active: 20

# mybatis第三方配置
mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  type-aliases-package: com.entity

无需手写 @Bean,Starter 自动创建 DruidDataSource、SqlSessionFactory、MapperScanner。

示例 2:Redis 第三方客户端配置

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    database: 0

自动注入 RedisTemplate<String, Object> 直接使用:

@Autowired
private RedisTemplate<String, Object> redisTemplate;

自定义覆盖第三方默认 Bean

自动配置的 Bean 不满足需求时,手动 @Bean 覆盖,@ConditionalOnMissingBean 会放弃自动创建:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 自定义序列化规则
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(serializer);
        template.setKeySerializer(new StringRedisSerializer());
        return template;
    }
}

五、常见第三方资源统一管理模板

1. 连接池类(Druid/HikariCP)

  • 核心第三方类:DruidDataSource
  • 配置方式:@ConfigurationProperties(prefix = "spring.datasource.druid")
  • 注入位置:给 MyBatis/JdbcTemplate 提供连接

2. ORM 框架(MyBatis)

  • 工厂 Bean:SqlSessionFactoryBean
  • 依赖:DataSource
  • 输出:Mapper 代理对象

3. 中间件客户端(RedisTemplate、RabbitTemplate、MongoTemplate)

SpringBoot starter 自动装配,可自定义序列化、连接池参数。

4. 文件 / OSS 第三方(阿里云 OSS、MinIO)

手动注册客户端 Bean:

@Bean
@ConfigurationProperties(prefix = "oss")
public OSS ossClient() {
    // 读取endpoint、accessKey、secret、bucket
    return new OSSClientBuilder().build(endpoint, ak, sk);
}

六、关键注解总结(第三方配置高频)

  1. @Configuration:标记配置类,用于注册第三方 Bean
  2. @Bean:将第三方类实例交给 IOC 容器
  3. @PropertySource:加载外部 properties 配置文件
  4. @Value("${key}"):单个属性注入
  5. @ConfigurationProperties(prefix="xxx"):批量绑定配置
  6. @ConditionalOnClass:存在第三方依赖才创建 Bean(自动配置核心)
  7. @ConditionalOnMissingBean:用户自定义 Bean 优先

七、优势:Spring 统一管理第三方资源

  1. 统一配置入口:所有第三方参数集中在配置文件,不用硬编码
  2. 统一生命周期:容器关闭自动销毁连接池、关闭客户端连接,释放资源
  3. 统一依赖注入:业务代码直接 @Autowired,不用手动 new 第三方对象
  4. 灵活扩展:可覆盖默认 Bean,自定义第三方组件行为(序列化、拦截器、连接参数)
  5. 环境隔离:通过多配置文件(dev/prod)切换第三方服务地址