Spring Boot自定义配置

  

前言

  在使用了SpringBoot项目中,我们能够体会到SpringBoot自动配置给我们带来的便利,它的核心思想是约定大于配置,尽管做到了绝大部分的配置。还是存在两个问题:一个是有些配置不在自动配置的范围,需要自定义配置;另一个是有些自动配置不能够很好的满足你的需要,需要对他们进行覆盖。所以我们还是经常需要使用到自定义配置,在SpringMVC的开发模式下,习惯于使用applicationContext.xml中进行相关配置。而SpringBoot推荐使用JavaConfig的方式来实现配置。

1、Spring配置

  首先介绍下Spring的几种配置方式:Spring 主要提供了XML、注解、JavaConfig等三种方式实现Bean的创建和注入。

  Spring有个核心的思想Ioc(控制反转),其中提到出了概念Bean,Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象。Spring容器会自动完成@bean对象的实例化。由Spring容器来负责Bean的实例化,装配和管理。

1.1 XML配置

  XML用来描述Bean的配置关系,Spring从XML配置文件中读取任何类型的元数据并自动转换成相应的Java代码。使用XML来配置Bean失去编译时的类型安全检查,同时大量的XML配置使得整个项目变得更加复杂。后续不推荐使用这种方式对Bean进行管理。

1.2 注解配置

  JDK1.5开始对注解进行支持,Spring提供了声明Bean的注解(如@Service、@Resource)减少很多配置量。Spring使用注解来描述Bean的配置与采用XML相比,因类注释是在一个类源代码中,可以获得类型安全检查的好处,可以良好地支持重构。

1.3 JavaConfig

  从Spring 3.x开始,Spring提供了Java配置的能力。Java配置是Spring4.x推荐的配置方式,可以完全替代xml配置;Java配置也是Spring Boot推荐的配置方式。

Spring的Java配置方式是通过 @Configuration 和 @Bean 这两个注解实现的:

①、@Configuration 作用于类上,相当于一个xml配置文件;

②、@Bean 作用于方法上,相当于xml配置中的<bean>;

1.3.1 定义Bean

  举例:

@Configuration
public class FeignClientLogConfig {
    @Bean
    Logger QjxFeign(){
        return new QjxFeignLogger();
    }
}

  这个配置等同于下面XML中的配置:

<beans> 
<bean id="FeignClientLogConfig" class="com.qjx.common.log.QjxFeignLogger "/> 
</beans>

  1.3.2 Bean依赖

  可以依赖其他任意数量的Bean,如果 cacheManager依赖redisTemplate代码如下:

@Configuration
@EnableCaching
public class RedisCacheConfig {
    
    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate){
        CacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
}
}

  这个配置等同于下面XML中的配置:

<beans> 
<bean id="cacheManager" class="com.qjx.config.RedisCacheConfig">
<property name="redisTemplate" ref="redisTemplate"></property> </bean> </beans>

  注意:bean的依赖的其他的必须也是Bean,就是说依赖的这个对象,在Spring容器中一定存在。使用JavaConfig时,把依赖放置在请求参数中,容易忽略这个问题。

2、自定义配置

  大多数情况下,自动配置的Bean满足模拟的需求,不用去覆盖它们。但是某些情况下,Spring Boot在自动装配的时候还不能很好的进行推断。这时,Spring Boot提供的解决方法是,覆盖自动配置的Bean。

  举个例子,我们数据库配置按照安全要求是需要进行密码加密的。但是在自动装配中,是不能够做这个个性化的操作的。所以需要覆盖自动装配的Bean。

       连接Redis数据库代码如下:

@Configuration
@EnableCaching
public class RedisCacheConfig {
    
    @Autowired
    private JedisConfig jedisConfig;
    
    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate){
        CacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
    }
    @Bean
    public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory factory){
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<String,String>();
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
    
    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
        redisConnectionFactory.setHostName(jedisConfig.getHost());
        redisConnectionFactory.setPort(jedisConfig.getPort());
        redisConnectionFactory.setPassword(decodeStr(jedisConfig.getPassword()));//Redis密码进行解密
        redisConnectionFactory.setTimeout(jedisConfig.getTimeout());
        redisConnectionFactory.setPoolConfig(jedisConfig.getPoolConfig());
        return redisConnectionFactory;
    }
    
    /**
     * 密码解密
     * @param encodeStr
     */
    public String decodeStr(String encodeStr) {
        UserAndPasswordAesBean.setSysId();
        return UserAndPasswordAesBean.decrypt(encodeStr);
    }
    
}

上述代码,将JedisConnectionFactory自动配置进行覆盖,在设置密码前,将配置文件中的密码使用解密方法解密。

总结:想要覆盖Spring Boot的自动配置,你所要做的仅仅是编写一个现实的配置。Spring Boot发现你的配置,随后降低自动配置的优先级,已你配置为准。

3、自定义配置的实现方式

  首先,Spring Boot自动配置自带了很多配置类,每一个都能运用在你的应用程序汇中。在使用了Spring4.0的条件下设置,可以在运行时判断这个配置是该被运用还是忽略。

举个列子,Redis的自动配置:

@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
    return applyProperties(createJedisConnectionFactory());
}

  其中JedisConnectionFactory的方法上添加了@Bean注解,在需要的时候可以配置出相应的Bean。但是上面还加了@ConditionalOnMissingBean,要求当前不存在RedisConnectionFactory类型的Bean时才生效。所有当已经有了一个Bean的时候,条件不满足,所有不会自动配置JedisConnectionFactory的Bean。

 

原文地址:https://www.cnblogs.com/lkd934/p/9531896.html