`
IT少年
  • 浏览: 74302 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java spring框架中方法级redis的连接自动获取和释放实现

阅读更多
java中使用redis总是需要处理redis连接的获取,释放等操作,每次使用都会使代码变的特别丑陋,模仿spring中aop的实现,用动态代理写一个 连接自动获取和释放的工具
主要思路 

JedisManageSupport 抽象类 类似于 aop的切入点,所有继承了该类(一般都是service层)的类,可以使用提供的获取redis的方法获取redis,并且不需要释放

JedisBeanPostProcessor 继承BeanPostProcessor  ,会在bean初始化时执行自己定义的逻辑:

如果A类继承了 JedisManageSupport ,就会获取redis连接并且放到JedisManageSupport 的成员变量里,A类的实例(其实是cglib动态代理生成的

A类的子类的实例)就可以使用该redis连接 进行相关操作了

代理类的实例见源码

源码如下
public class JedisBeanPostProcessor implements BeanPostProcessor {

@Autowired
ShardedJedisPool shardedJedisPool;

static final Logger logger = Logger.getLogger(JedisBeanPostProcessor.class);

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof JedisManageSupport) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(bean.getClass());
enhancer.setCallback(new JedisInterceptor(shardedJedisPool, bean));
Object targetBean = enhancer.create();
return targetBean;
}
else {
return bean;
}
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

class JedisInterceptor implements MethodInterceptor {

static final Logger logger = Logger.getLogger(JedisInterceptor.class);

ShardedJedisPool pool;

Object src;

public JedisInterceptor(ShardedJedisPool pool, Object src) {
this.pool = pool;
this.src = src;
}

@Override
public Object intercept(Object target, Method method, Object[] arguments, MethodProxy methodProxy) throws Throwable {
Object result = null;
if (target instanceof JedisManageSupport) {
if (this.isDeclaredMethod(target, method)) {
ShardedJedis jedis = null;
try {
JedisManageSupport support = (JedisManageSupport) src;
jedis = pool.getResource();
support.setShardedJedis(jedis);
// logger.debug("调用之前注入jedis对象,method:" + method);
/**
* 下面代码可以使用 method.invoke(src,arguments)。 不能使用
* methodProxy.invokeSuper(target,arguments);
* 因为A类中用Autowired注入的属性,生成代理的子类B后,因为子类B是新建的类。从父类继承的属性没有被初始化,
* 使用methodProxy.invokeSuper()执行是,会报空指针异常.
*/
result = methodProxy.invoke(src, arguments);
support.setShardedJedis(null);
}
catch (Exception e) {
pool.returnBrokenResource(jedis);
e.printStackTrace();
}
finally {
if (jedis != null) {
pool.returnResource(jedis);
}
// logger.debug("调用之后归还jedis对象,method:" + method);
}
}
else {
result = methodProxy.invoke(src, arguments);
}
}
else {
throw new Exception("使用该代理必须继承JedisManageSupport");
}
return result;
}

/**
* 是否是target类本身定义的非私有的方法,还是继承的父类
* @return true是target自己类的并且不是私有的的,
*/
private boolean isDeclaredMethod(Object target, Method arg1) {
Method temp = null;
try {
temp = target.getClass().getDeclaredMethod(arg1.getName(), arg1.getParameterTypes());
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 不为null,并且是非私有的,返回true
*/
if (temp != null) {

return true;
}
else {
return false;
}
}
}



public abstract class JedisManageSupport {
ThreadLocal<ShardedJedis> jedisHolder = new ThreadLocal<ShardedJedis>();

public final ShardedJedis getShardedJedis() {
return jedisHolder.get();
}

public final void setShardedJedis(ShardedJedis jedis) {
jedisHolder.set(jedis);
}

/**
* 如果某个键不同单位之间也不会重复,可以使用这个方法生成redis的键
*/
public final byte[] assemKey(String baseKey) {
Assert.isTrue(StringUtils.isNotBlank(baseKey), "参数不能为空");
return baseKey.getBytes();
}

/**
* 根据tableName+prefix 构造唯一key与assemKey(String baseKey, String tableName)
* 规则一致
*/
public final byte[] assemKeyByPrefix(String tableName, String baseKey) {
Assert.isTrue(StringUtils.isNotBlank(baseKey), "参数不能为空");
Assert.isTrue(StringUtils.isNotBlank(tableName), "参数不能为空");
UnitInfo unit = WebService.getUnitInfo();
Assert.isTrue(unit != null, "单位信息获取不到");
return (tableName + "-" + unit.getPrefix() + "-" + baseKey).getBytes();
}

/**
*
* 不同前缀的表中可能有相同的键,同一个表中也可能是有重复的baseKey时,用这个生成redis的key 比如 用户信息表的
* username字段,不同的用户信息表允许重复的username,mooc_t_userinfo
* 也允许有相同的账号,所以生成redis的key时,需要用到单位的mooc_school 放入redis中
*/
public final byte[] assemKeyByFid(String tableName, String baseKey) {
UnitInfo unit = WebService.getUnitInfo();
Assert.isTrue(unit != null, "单位信息获取不到");
return (tableName + "-" + unit.getMoocSchool() + "-" + baseKey).getBytes();
}

}
分享到:
评论

相关推荐

    Java EE互联网轻量级框架整合开发 SSM框架(Spring MVC+Spring+MyBatis)和Redis实现.rar

    Java EE互联网轻量级框架整合开发,主要集中在SSM框架的使用上,即Spring MVC、Spring和MyBatis的集成,以及Redis缓存技术的引入。这个主题旨在提高Web应用的开发效率,优化性能,同时降低项目的复杂度。 首先,...

    java中spring框架使用redis所需的5个jar包

    在Java开发中,Spring框架是广泛应用的轻量级框架,它提供了一种模块化和简化的方式来构建企业级应用。而Redis则是一种高性能的键值存储系统,常被用于缓存、消息队列以及数据持久化等多种场景。当我们在Spring框架...

    Spring mvc整合redis实例(redis连接池)

    在Maven项目中,可以在pom.xml文件中添加`spring-data-redis`和`jedis`库,这两个库分别提供了Spring对Redis的支持和Jedis,一个Java客户端连接Redis。 ```xml &lt;groupId&gt;org.springframework.data &lt;artifactId&gt;...

    springMybatis+redis三级缓存框架

    Spring的`@Autowired`注解可以自动装配MyBatis的SqlSessionFactory和SqlSessionTemplate,而Spring的数据源配置则可以方便地与Redis连接。在Spring中,我们可以通过RedisTemplate或JedisTemplate操作Redis,实现数据...

    springcloud部署redis集群

    在SpringCloud框架中,部署Redis集群是实现高可用、数据持久化和分布式缓存的关键步骤。Redis是一款高性能的键值数据库,广泛应用于缓存、消息队列等多种场景。SpringCloud通过集成Spring Data Redis模块,使得在...

    spring 和redis整合,java代码操作redis,java代码中选择redis制定数据库

    在Java开发中,Spring框架与Redis的整合是一个常见的需求,特别是在构建高性能、高并发的应用时。Redis是一款开源的、基于键值对的数据存储系统,它提供了高速的数据读写能力,适用于缓存、消息队列等多种场景。而...

    Spring3.0整合redis相关jar

    在IT行业中,Spring框架是Java应用开发中的一个关键组件,它提供了一个全面的编程和配置模型,用于简化企业级应用的复杂性。而Redis则是一款高性能的键值存储系统,常用于数据库、缓存和消息代理等场景。将Spring与...

    spring + ehcache + redis两级缓存

    当我们谈论“Spring + Ehcache + Redis”两级缓存时,我们实际上是在讨论如何在Java环境中利用Spring框架来集成Ehcache作为本地缓存,并利用Redis作为分布式二级缓存,构建一个高效且可扩展的缓存解决方案。...

    ssm框架整合redis源码

    整合SSM和Redis的过程涉及到Java Web开发、Spring框架、SpringMVC、MyBatis以及Redis缓存等多个技术领域,对于提升系统的可扩展性和性能有着显著的作用。同时,这也要求开发者对这些技术有深入的理解,以便更好地...

    Redis集成Spring的Java代码

    集成Redis到Spring框架中可以极大地提升应用的响应速度和数据处理能力。本篇文章将详细探讨如何通过Java代码实现Redis与Spring的整合,并介绍相关的操作,如增删改查、列表操作以及批量操作,以提高性能。 首先,要...

    spring-data-redis 1.7.6

    Spring Data Redis是Spring框架下的一个模块,专注于提供对Redis数据存储系统的高效支持。Redis是一个高性能的键值数据库,它以其丰富的数据结构、高效的性能以及广泛的应用场景深受开发者喜爱。Spring Data Redis...

    Spring-session2整合spring5+redis

    标题中的“Spring-session2整合spring5+redis”指的是在Spring框架的第五个主要版本(Spring 5)中,集成Spring Session 2与Redis数据库来管理Web应用的会话(Session)。Spring Session是一个开源项目,旨在提供一...

    SpringDataRedis的jar包.rar

    只需在`application.properties`或`application.yml`中配置Redis服务器的相关属性(如主机名、端口、密码等),即可实现自动连接。 2. **RedisTemplate**:这是Spring Data Redis的核心组件,它提供了一套丰富的...

    Spring+redis5.05配置过程.docx

    在本文档中,我们提供了完整的代码实现,包括 Spring 配置文件、Java 代码和 Redis 配置文件。这些代码可以帮助您快速了解如何配置 Spring 和 Redis 5.05,并实现高效的缓存和数据存储。 总结 在本文档中,我们...

    Spring+Struts2+hibernate+Redis整合

    1. **Spring框架**:Spring是企业级Java应用的核心框架,它提供了依赖注入(DI)和面向切面编程(AOP)等核心特性,使得代码更加模块化和易于管理。在SSH+Redis的整合中,Spring不仅作为业务层的管理框架,还可以通过其...

    spring中使用redis

    在Spring框架中集成Redis,是为了利用Redis作为高效的数据缓存,提高应用的性能。Redis是一个内存中的数据结构存储系统,可以作为数据库、缓存和消息中间件使用。它支持多种数据结构,如字符串、哈希、列表、集合、...

    java spring集成redis所需库包

    在Java Spring框架中集成Redis作为缓存或消息队列是一个常见的需求。Redis是一个高性能的键值存储系统,常用于数据库、缓存和消息代理。在Java应用中使用Spring框架进行集成,可以极大地提升应用程序的数据处理效率...

    Java 中使用 redis

    结合Spring MVC框架,我们可以轻松地在Java Web应用中集成Redis,以提升应用的性能和响应速度。下面将详细介绍如何在Java中使用Redis以及Spring MVC中的拦截器来获取并保存对象。 1. **安装与配置Redis** - 首先,...

    spring整合redis项目

    Redis是一款开源的、高性能的键值对数据库,而Spring是Java领域广泛使用的框架,提供了一整套的企业级应用开发工具。将Spring与Redis结合,可以方便地在应用程序中利用Redis的强大功能。 一、Spring Data Redis概述...

    spring boot+jpa+redis集群

    首先,Spring Boot是Spring框架的简化版本,它通过自动配置和起步依赖来简化项目设置,让开发者可以快速地搭建基于Spring的应用。Spring Boot提供了一个内置的Tomcat服务器,使得我们可以直接运行应用程序而无需额外...

Global site tag (gtag.js) - Google Analytics