老师,为什么要用内部类呢

来源:11-4 引入缓存技术之配置讲解

慕斯6088333

2019-03-26

public class JedisUtil {
	/** 操作Key的方法 */
	public Keys KEYS;
	/** 对存储结构为String类型的操作 */
	public Strings STRINGS;

	/** Redis连接池对象 */
	private JedisPool jedisPool;

	/**
	 * 获取redis连接池
	 * 
	 * @return
	 */
	public JedisPool getJedisPool() {
		return jedisPool;
	}

	/**
	 * 设置redis连接池
	 * 
	 * @return
	 */
	public void setJedisPool(JedisPoolWriper jedisPoolWriper) {
		this.jedisPool = jedisPoolWriper.getJedisPool();
	}

	/**
	 * 从jedis连接池中获取获取jedis对象
	 * 
	 * @return
	 */
	public Jedis getJedis() {
		return jedisPool.getResource();
	}
		// *** Inner class *//
	public class Keys {

		/**
		 * 清空所有key
		 */
		public String flushAll() {
			Jedis jedis = getJedis();
			String stata = jedis.flushAll();
			jedis.close();
			return stata;
		}
		//其他方法。 

为什么这里要用内部类来实现呢,有什么好处呢。。以及这里对于内部类的对象是 public 的访问权限。。这样的访问权限是不是会太大了。这里是什么设计模式么或者面向对象设计原则么~?

如果我这里改成把内部类的对象作为外部类的静态成员好不好呢。。并把外部类的构造方法私有化,变成单例模式。并设置getter 来访问内部成员。

代码如下,我还没测试过QAQ,在学校没有家里的电脑。


public class JedisUtil {

	
	/** 操作Key的方法 */
	private static KEYS keysInstance = new Keys();
	/** 对存储结构为String类型的操作 */
	private static Strings stringsInstance = new Strings();

	/** private constructor for singleton**/
	private JedisUtil(){
		
	}
	
	/** Redis连接池对象 */
	private JedisPool jedisPool;

	/**
	 * 获取redis连接池
	 * 
	 * @return
	 */
	public JedisPool getJedisPool() {
		return jedisPool;
	}

	/**
	 * 设置redis连接池
	 * 
	 * @return
	 */
	public void setJedisPool(JedisPoolWriper jedisPoolWriper) {
		this.jedisPool = jedisPoolWriper.getJedisPool();
	}

	/**
	 * 从jedis连接池中获取获取jedis对象
	 * 
	 * @return
	 */
	public Jedis getJedis() {
		return jedisPool.getResource();
	}


	public static KEYS getKeys(){
		return keysInstance;
	}

	public static Strings getStrings(){
		return stringsInstance;
	}

	// *******************************************Keys*******************************************//
	private class Keys {
	
		/**
		 * 清空所有key
		 */
		public String flushAll() {
			Jedis jedis = getJedis();
			String stata = jedis.flushAll();
			jedis.close();
			return stata;
		}

		/**
		 * 删除keys对应的记录,可以是多个key
		 * 
		 * @param String
		 *            ... keys
		 * @return 删除的记录数
		 */
		public static long del(String... keys) {
			Jedis jedis = getJedis();
			long count = jedis.del(keys);
			jedis.close();
			return count;
		}
// etc.
		

serviceImpl:

Service
public class HeadLineServiceImpl implements HeadLineService {
	@Autowired
	private HeadLineDao headLineDao;
	@Autowired
	private JedisUtil jedisUtil;
	@Autowired
	private JedisUtil.Keys jedisKeys;// 这个好像多余了。
	@Autowired
	private JedisUtil.Strings jedisStrings;// 这个好像多余了。
	
	
	private static Logger logger = LoggerFactory.getLogger(HeadLineServiceImpl.class);

	@Override
	@Transactional
	public List<HeadLine> getHeadLineList(HeadLine headLineCondition) {
		// 定义redis的key前缀
		String key = HLLISTKEY;
		// 定义接收对象
		List<HeadLine> headLineList = null;
		// 定义jackson数据转换操作类
		ObjectMapper mapper = new ObjectMapper();
		
		JedisUtil.Keys jedisKeys = jedisUtil.getKEYS();
		JedisUtil.Strings jedisStrings = jedisUtil.getString();
		// 拼接出redis的key
		if (headLineCondition != null && headLineCondition.getEnableStatus() != null) {
			key = key + "_" + headLineCondition.getEnableStatus();
		}
		// 判断key是否存在
		if (!jedisKeys.exists(key)) {
			// 若不存在,则从数据库里面取出相应数据
			headLineList = headLineDao.queryHeadLine(headLineCondition);

不知道这么做是否可以。depedency injection 只要引入util类就可以了吧~?

谢谢老师。如果老师能帮我试试就更好了TAT。。

写回答

1回答

慕斯6088333

提问者

2019-03-26

spring-redis.xml

这个也是单例模式的 :连接池对象 虽然不写也是单例的
-<bean class="com.imooc.o2o.cache.JedisPoolWriper" id="jedisWritePool" depends-on="jedisPoolConfig"scope="singleton">

<constructor-arg ref="jedisPoolConfig" index="0"/>

<constructor-arg value="${redis.hostname}" index="1"/>

<constructor-arg value="${redis.port}" index="2" type="int"/>

</bean>

<!-- 创建Redis工具类,封装好Redis的连接以进行相关的操作 -->



-<bean class="com.imooc.o2o.cache.JedisUtil" id="jedisUtil" scope="singleton">


-<property name="jedisPool"> 

<ref bean="jedisWritePool"/>

</property>

</bean>

<!-- Redis的key操作 这个应该不用注册了--> 
-<bean class="com.imooc.o2o.cache.JedisUtil$Keys" id="jedisKeys" scope="singleton">

<constructor-arg ref="jedisUtil"/>

</bean>

<!-- Redis的Strings操作  这个应该不用注册了 -->
-<bean class="com.imooc.o2o.cache.JedisUtil$Strings" id="jedisStrings" scope="singleton">

</bean>


因为内部类如果是非静态的。那么就是依赖于外部类的对象所存在的。而如果是静态内部类的话是可以独立与外部类的对象而独立存在的。所以如果定义为私有的内部类。那么就是相当于和普通方法和属性一样了,不需要配置一个inner bean 了。这样理解对嘛。。

感觉inner bean 应该配置给静态内部类(嵌入类)。他们相对于外部类的联系性更低。

0
2
慕斯6088333
回复
翔仔
哈哈,好的好的。写内部类会比较好。也比较省一些ioc的配置。
2019-03-29
共2条回复

Java双版本(SSM到SpringBoot)校园商铺全栈开发

SSM商铺V1.0,解决毕设痛点;SpringBoot商铺V2.0,满足工作刚需

5113 学习 · 8144 问题

查看课程