J2Cache的SpringBootのStarter


声明:本文转载自https://my.oschina.net/qixiaobo025/blog/1580651,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

背景

J2Cache是OsChina的两级缓存实现框架 但是代码比较老 代码考虑也比较死板 不支持多种配置

对于多profile的实现来说也 只能使用通过Maven的profile实现【不支持动态变更】

public class J2Cache {           private final static Logger log = LoggerFactory.getLogger(J2Cache.class);           private final static String CONFIG_FILE = "/j2cache.properties";       private final static CacheChannel channel;       private final static Properties config;           static {           try {               config = loadConfig();               String cache_broadcast = config.getProperty("cache.broadcast");               if ("redis".equalsIgnoreCase(cache_broadcast))                   channel = RedisCacheChannel.getInstance();               else if ("jgroups".equalsIgnoreCase(cache_broadcast))                   channel = JGroupsCacheChannel.getInstance();               else                   throw new CacheException("Cache Channel not defined. name = " + cache_broadcast);           } catch (IOException e) {               throw new CacheException("Unabled to load j2cache configuration " + CONFIG_FILE, e);           }       }           public static CacheChannel getChannel(){           return channel;       }           public static Properties getConfig(){           return config;       }           /**        * 加载配置        * @return        * @throws IOException        */       private static Properties loadConfig() throws IOException {           log.info("Load J2Cache Config File : [{}].", CONFIG_FILE);           InputStream configStream = J2Cache.class.getClassLoader().getParent().getResourceAsStream(CONFIG_FILE);           if(configStream == null)               configStream = CacheManager.class.getResourceAsStream(CONFIG_FILE);           if(configStream == null)               throw new CacheException("Cannot find " + CONFIG_FILE + " !!!");               Properties props = new Properties();               try{               props.load(configStream);           }finally{               configStream.close();           }               return props;       }       }

很明显此处代码必须要读取j2cache.properties

那么在不同环境【profile】想要使用不同的配置只有通过maven在编译时修改配置文件了【或者同样的其他手段】

思路

  1. 为了最小化的修改代价 不建议直接将所有的配置放到SpringBoot的application-${profile}.properties中 因为比如其他Jar中都是依靠J2Cache.getChannel() 来获取对应的cacheChannel
  2. 那么我们可以修改读取的配置文件即可【换言之我们考虑读取不同的j2cache.properties】
  3. 保留静态方法 但是静态代码块移除【以免一旦加载到该Class就会直接初始化】
  4. 在getChannel等方法做检查必须提前调用初始化方法

方案

/**  * 缓存入口  *  * @author winterlau  */ public class J2Cache {       private final static Logger log = LoggerFactory.getLogger(J2Cache.class);       private final static String CONFIG_FILE = "/j2cache.properties";     private static CacheChannel channel;     private static Properties config;     private static AtomicBoolean initlized = new AtomicBoolean(false);         public static void init() {         init(CONFIG_FILE);     }       public static void init(String filePath) {         if (initlized.compareAndSet(false, true)) {             try {                 config = loadConfig(filePath);                 String cache_broadcast = config.getProperty("cache.broadcast");                 if ("redis".equalsIgnoreCase(cache_broadcast)) {                     channel = RedisCacheChannel.getInstance();                 } else if ("jgroups".equalsIgnoreCase(cache_broadcast)) {                     channel = JGroupsCacheChannel.getInstance();                 } else {                     initlized.set(false);                     throw new CacheException("Cache Channel not defined. name = " + cache_broadcast);                 }             } catch (IOException e) {                 initlized.set(false);                 throw new CacheException("Unabled to load j2cache configuration " + filePath, e);             }         } else {             log.warn("J2cache initlized alerday!");         }     }       private static void checkInitlized() {         if (!initlized.get()) {             throw new CacheException("J2cache init not yet! You should call j2Cache.init(String) first!");         }     }       public static CacheChannel getChannel() {         checkInitlized();         return channel;     }       public static Properties getConfig() {         checkInitlized();         return config;     }       /**      * 加载配置      *      * @param filePath      * @return      * @throws IOException      */     private static Properties loadConfig(String filePath) throws IOException {         if (filePath == null || filePath.trim().length() == 0) filePath = CONFIG_FILE;         log.info("Load J2Cache Config File : [{}].", filePath);         InputStream configStream = J2Cache.class.getResourceAsStream(filePath);         if (configStream == null)             configStream = CacheManager.class.getResourceAsStream(filePath);         if (configStream == null)             throw new CacheException("Cannot find " + filePath + " !!!");           Properties props = new Properties();           try {             props.load(configStream);         } finally {             configStream.close();         }           return props;     }   }

基于目前SpringBoot的使用我们创建对应的Starter

创建配置类

package net.oschina.j2cache.autoconfigure;   import org.springframework.boot.context.properties.ConfigurationProperties;   @ConfigurationProperties(prefix = "j2cache") public class J2CacheConfig {     private String configLocation = "/j2cache.properties";       public String getConfigLocation() {         return configLocation;     }       public void setConfigLocation(String configLocation) {         this.configLocation = configLocation;     } }

创建初始化调用类

package net.oschina.j2cache.autoconfigure;   import net.oschina.j2cache.J2Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory;   import javax.annotation.PostConstruct;   public class J2CacheIniter {     private static Logger logger = LoggerFactory.getLogger(J2CacheIniter.class);     private final J2CacheConfig j2CacheConfig;       public J2CacheIniter(J2CacheConfig j2CacheConfig) {         this.j2CacheConfig = j2CacheConfig;     }       @PostConstruct     public void init() {         J2Cache.init(j2CacheConfig.getConfigLocation());     } }

根据条件判断加载

package net.oschina.j2cache.autoconfigure;   import net.oschina.j2cache.J2Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration;   @ConditionalOnClass(J2Cache.class) @EnableConfigurationProperties({J2CacheConfig.class}) @Configuration public class J2CacheAutoConfigure {     private static Logger logger = LoggerFactory.getLogger(J2CacheAutoConfigure.class);       private final J2CacheConfig j2CacheConfig;       public J2CacheAutoConfigure(J2CacheConfig j2CacheConfig) {         this.j2CacheConfig = j2CacheConfig;     }       @ConditionalOnMissingBean(J2CacheIniter.class)     public J2CacheIniter j2CacheIniter() {         return new J2CacheIniter(j2CacheConfig);     }     }

创建META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ net.oschina.j2cache.autoconfigure.J2CacheAutoConfigure

这样就会自动加载对应的

J2CacheAutoConfigure  可以参考SpringBoot之自动配置

使用

系统中我们使用J2Cache作为SpringCache的实现

比如我们可以如此

/*  * Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.  * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.  * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.  * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.  * Vestibulum commodo. Ut rhoncus gravida arcu.  */   package com.f6car.base.config;   import net.oschina.j2cache.autoconfigure.J2CacheConfig; import net.oschina.j2cache.autoconfigure.J2CacheIniter; import org.nutz.j2cache.spring.SpringJ2CacheManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.CacheManager; import org.springframework.cache.ehcache.EhCacheManagerUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.PropertySource;   @Configuration @PropertySource("classpath:j2cache/j2cache-${spring.profiles.active}.properties") public class CacheConfig {     @Value("${ehcache.ehcache.name}")     private String ehcacheName;       @Bean("ehCacheManager")     public net.sf.ehcache.CacheManager ehCacheManager() {         return EhCacheManagerUtils.buildCacheManager(ehcacheName);     }       @DependsOn({"ehCacheManager", "j2CacheIniter"})     @Bean     public CacheManager springJ2CacheManager() {         return new SpringJ2CacheManager();     }       @Bean("j2CacheIniter")     public J2CacheIniter j2CacheIniter(J2CacheConfig j2cacheConfig) {         return new J2CacheIniter(j2cacheConfig);     }   }

如上我们就可以加载到不同的j2cache/j2cache-${spring.profiles.active}.properties

这样就完成了J2cache的初始化

本文发表于2017年11月28日 10:33
(c)注:本文转载自https://my.oschina.net/qixiaobo025/blog/1580651,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2477 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1