编写自己的工具starter类 (一)- spring-boot-redis-starter

开始

spring-boot 为什么现在这么火了,因为它解决了很多配置信息文件

实现了集成一个组件,装箱即用的效果。也就是约定大于配置。

平常工作中,我们也可以开发自己的starter包,下面以我写的一个工具包为例

需求

写一个redis的客户端spring boot工具包,同时能够实现连接 单点,哨兵,cluster。

代码已经上传至github 快速入口

使用方法

1,把我github的项目下载下来,打成jar导入到自己的maven库或者公司的私服。

2,pom引入jia,

<dependency>
    <groupId>com.shrek</groupId>
    <artifactId>spring-boot-redis-starter</artifactId>
    <version>${shrek.version}</version>
</dependency>

3,springboot的启动类加上注解 @EnableRedis(value = RedisModeConstants.REDIS_CLUSTER)

4,application.yml加配置自己的redis配置信息,具体参考com\shrek\redis\starter\properties\RedisProperties.java

shrek:
  redis:
    enable: true
    host: 192.168.233.106
    # cluster: 192.168.89.132:6379,192.168.89.132:6380,192.168.89.132:6381,192.168.89.132:6382,192.168.89.132:6383,192.168.89.132:6384

实现

  1. 首先,建立一个redis-cluster,可以查看我以前的博客 快速入口
  2. 代码的一些关键代码。

classpath:META-INF/spring.factories文件是springboot启动时,

org.spring.framework.core.io.support.SpringFactoriesLoader会扫描的文件,

下面是RedisInitAutoConfiguraion类

@Configuration
@ConditionalOnProperty(prefix = RedisProperties.PREFIX, name = "enable", havingValue = "true")
@EnableConfigurationProperties(value = RedisProperties.class)
public class RedisInitAutoConfiguration {
    /**
     * 初始化 applicationContext 工具类,
     * 当类继承 ApplicationContextAware ,会调用setApplicationContext
     * @author 吴署
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public RedisBeanUtil beanUtil() {
        return new RedisBeanUtil();
    }

    @Bean
    @ConditionalOnMissingBean(ShrekRedisTemplate.class)
    public ShrekRedisTemplate easyRedisTemplate() {

        return new ShrekRedisTemplate();
    }

    @Bean
    @ConditionalOnMissingBean(JedisConnectionFactory.class)
    public JedisConnectionFactory jedisConnectionFactory(RedisProperties redisProperties) {

        return RedisConnectionFactoryUtil.init(redisProperties);
    }
}

这个类的主要作用

1,首先这是一个配置类 @Configuration

2,指定我的读取配置类RedisProperties

3,beanUtil()                                                                              初始化applicationContext,

      jedisConnectionFactory(RedisProperties redisProperties)  通过配置信息jedisConnectionFactory

      shrekRedisTemplate()                                                          客户端操作

EnableRedis.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RedisConfigRegistrar.class)
public @interface EnableRedis {

    String value() default RedisModeConstants.REDIS_SINGLE;

}

这个类是启动注解类,在springboot 启动类注解@EnableRedis(value = RedisModeConstants.REDIS_CLUSTER)

指定redis-client是cluster集群客户端,这里又@Import(RedisConfigRegistrar.class)导入了RedisConfigRegistrar类

RedisConfigRegistrar.java

RedisConfigRegistrar继承了ImportBeanDefinitionRegistrar , BeanFactoryAware,所以可以在这里

往beanfactory里注入client的Process类。

/**
 * redis 配置初始化
 * spring  类继承ImportBeanDefinitionRegistrar , BeanFactoryAware
 * @author 吴署
 */
public class RedisConfigRegistrar implements ImportBeanDefinitionRegistrar , BeanFactoryAware{

    private BeanFactory beanFactory;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {

        //得到启动类注解的@EnableRedis(value = RedisModeConstants.REDIS_CLUSTER)
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(
                EnableRedis.class.getName()));
        //获取启动类注解的client的类型
        String redisMode = attributes.getString("value");

        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) this.beanFactory;
        // 通过BeanDefinitionBuilder创建bean定义,
        // 并注册到spring bean factory 工厂
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisEnvironment.class);
        defaultListableBeanFactory.registerBeanDefinition(RedisEnvironment.class.getName(),beanDefinitionBuilder.getBeanDefinition());

        beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisAdapter.class);
        defaultListableBeanFactory.registerBeanDefinition(RedisAdapter.class.getName(),beanDefinitionBuilder.getBeanDefinition());

        beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisSingleProcessor.class);
        defaultListableBeanFactory.registerBeanDefinition(RedisSingleProcessor.class.getName(),beanDefinitionBuilder.getBeanDefinition());

        beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisClusterProcessor.class);
        defaultListableBeanFactory.registerBeanDefinition(RedisClusterProcessor.class.getName(),beanDefinitionBuilder.getBeanDefinition());

        beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisSentinelProcessor.class);
        defaultListableBeanFactory.registerBeanDefinition(RedisSentinelProcessor.class.getName(),beanDefinitionBuilder.getBeanDefinition());


        factoryInit(redisMode);
    }

    /**
     * 修改bean中RedisEnvironment的是否初始化属性
     * 和设置bean中RedisAdapter的redis客户端类型
     * @param redisMode
     */
    private void factoryInit(String redisMode) {
        RedisEnvironment redisEnvironment = (RedisEnvironment) this.beanFactory.getBean(RedisEnvironment.class.getName());
        redisEnvironment.setRedisConnectionFactoryIsInit(Boolean.TRUE);

        RedisAdapter redisAdapter = (RedisAdapter) this.beanFactory.getBean(RedisAdapter.class.getName());
        redisAdapter.setRedisMode(redisMode);
    }

    /**
     * 重写BeanFactoryAware的setBeanFactory,
     * 将spring的beanFactory赋给this.beanFactory
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory=beanFactory;
    }

猜你喜欢

转载自blog.csdn.net/shrek11/article/details/103250448