- 浏览: 1734348 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (337)
- javaScript校验 (11)
- java (31)
- java连接数据库 (1)
- js应用 (41)
- JQuery (15)
- linux操作命令 (12)
- loadrunner测试 (5)
- tomcat (18)
- 数据库 (12)
- eclipse (7)
- 触发器 (7)
- 表单 (3)
- ibatis (6)
- oracle (4)
- xml (1)
- Exception (6)
- spring (16)
- struts (4)
- struts 标签 (2)
- sql (8)
- sql server (6)
- 其它 (18)
- Apache (2)
- 电脑故障 (4)
- java 线程 (1)
- dwr (8)
- jackey (18)
- 总结 (34)
- gcc linux (2)
- extjs 学习 (5)
- 网站建设 (4)
- 健康 (2)
- 房地产知识 (1)
- hibernate (3)
- mysql (7)
- linux (13)
- svn (1)
最新评论
-
阳光泛滥的日子:
很好用谢谢
java.net.URISyntaxException的解决办法 -
linjianqing:
现在有更好的处理方式吗?我正也为这发愁
applet访问打印机出现的问题 -
ruyi574812039:
非常感谢您的总结!想问几个问题!假设三个项目分别以静态部署的三 ...
在Tomcat中部署Web程序的几种方式 -
yangguo:
太j8麻烦了
Spring3.1中使用缓存注解及Shiro的缓存联合 -
bellawang:
很好用谢谢
java.net.URISyntaxException的解决办法
Spring3.1中使用缓存注解及Shiro的缓存联合
- 博客分类:
- spring
Spring最近释出了3.1的REALEASE版本,到我写这篇日志的时候已经是3.1.2.REALEASE版本了,该版本直接内置了Ehcache的缓存注解,比起以前配置上是容易了许多,但是shiro官方却并没有为此3.1版本的注解缓存更新其最新的实现方式,为了能够用上最新版本的spring和shiro(1.2.1),特别针对缓存部分做了一些修改。
首先Spring 3.1及以后版本的cache功能位于spring-context包中,要使用spring3.1的缓存注解,只需要在spring的主配置xml文件中添加schema:
1
|
xmlns:cache="http://www.springframework.org/schema/cache"
|
记得在xsi:schemaLocation中增加:
1
|
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
|
注意:cache的schemaLocation暂时不支持不写版本号的xsd,也就是说,现在还必须写上spring-cache-3.1.xsd
然后写上
1
|
<cache:annotation-driven/>
|
就可以使用注解@Cacheable和@CacheEvict了
@Cacheable:要缓存的方法或者类,属性:value、key、condition,value是最主要的,对应ehcache.xml中声明的cache的name;key的主要作用我认为是给局部更新缓存使用的,并且支持SpEL;condition是触发条件,空表示全部增加,也支持SpEL。
@CacheEvict:要进行清空缓存的方法或者类,属性:value、key、condition、allEntries、beforeInvocation,前三者与@Cacheable类似,allEntries为true表示清空全部缓存,默认为false;beforeInvocation为true表示在方法执行以前清理缓存,默认为false
当然,如果想要详细的配置,就需要在xml中添加一些东西了:
1
2 3 4 5 6 7 8 9 10 11 12 13 |
<cache:annotation-driven cache-manager="cacheManager"/>
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:/config/ehcache.xml" /> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="cacheManagerFactory" /> </bean> |
以上Spring 3.1的缓存注解就已经OK了,接下去就是Shiro的部分。
shiro目前还不支持直接使用上述Spring 3.1的配置,但是我们可以改造一下:
首先得写两个类进行注入:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
/**
* */ package org.apache.shiro.cache.ehcacheSpring3_1; import java.io.IOException; import java.io.InputStream; import org.apache.shiro.ShiroException; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; import org.apache.shiro.config.ConfigurationException; import org.apache.shiro.io.ResourceUtils; import org.apache.shiro.util.Destroyable; import org.apache.shiro.util.Initializable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.ehcache.EhCacheCacheManager; /** * @author Yockii * */ public class EhCacheManager implements CacheManager, Initializable, Destroyable { private static final Logger log = LoggerFactory.getLogger(EhCacheManager.class); protected org.springframework.cache.ehcache.EhCacheCacheManager manager; private boolean cacheManagerImplicitlyCreated = false; private String cacheManagerConfigFile = "classpath:org/apache/shiro/cache/ehcache/ehcache.xml"; public EhCacheManager(){} public org.springframework.cache.ehcache.EhCacheCacheManager getCacheManager(){ return manager; } public void setCacheManager(org.springframework.cache.ehcache.EhCacheCacheManager manager){ this.manager = manager; } public String getCacheManagerConfigFile(){ return this.cacheManagerConfigFile; } public void setCacheManagerConfigFile(String classpathLocation){ this.cacheManagerConfigFile = classpathLocation; } protected InputStream getCacheManagerConfigFileInputStream(){ String configFile = getCacheManagerConfigFile(); try{ return ResourceUtils.getInputStreamForPath(configFile); } catch (IOException e) { throw new ConfigurationException("Unable to obtain input stream for cacheManagerConfigFile [" + configFile + "]", e); } } /* (non-Javadoc) * @see org.apache.shiro.util.Destroyable#destroy() */ @Override public void destroy() throws Exception { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.apache.shiro.util.Initializable#init() */ @Override public void init() throws ShiroException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.apache.shiro.cache.CacheManager#getCache(java.lang.String) */ @Override public final <K, V> Cache<K, V> getCache(String name) throws CacheException { if(log.isTraceEnabled()){ log.trace("Acquiring EhCache instance named [" + name + "]"); } try{ org.springframework.cache.Cache cache = manager.getCache(name); if(cache == null){ if(log.isInfoEnabled()){ log.info("Cache with name '{}' does not yet exist. Creating now.", name); } this.manager.getCacheManager().addCache(name); cache = manager.getCache(name); if(log.isInfoEnabled()){ log.info("Added EhCache named [" + name + "]"); } } else { if(log.isInfoEnabled()){ log.info("Using existing EHCache named [" + cache.getName() + "]"); } } return new EhCache<K, V>(cache); } catch (Exception e) { throw new CacheException(e); } } private EhCacheCacheManager ensureCacheManager(){ try{ if(this.manager == null){ if(log.isDebugEnabled()){ log.debug("cacheManager property not set. Constructing CacheManager instance... "); } this.manager = new org.springframework.cache.ehcache.EhCacheCacheManager(); manager.setCacheManager(new net.sf.ehcache.CacheManager(getCacheManagerConfigFileInputStream())); if(log.isTraceEnabled()){ log.trace("instantiated Ehcache CacheManager instance WITH SPRING EhCacheCacheManager"); } cacheManagerImplicitlyCreated = true; if(log.isDebugEnabled()){ log.debug("implicit cacheManager created WITH SPRING EhCacheCacheManager successfully."); } } return this.manager; } catch (Exception e) { throw new CacheException(e); } } } |
这个是主要的缓存管理类,还有一个缓存类hack类Ehcache
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
/**
* */ package org.apache.shiro.cache.ehcacheSpring3_1; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import net.sf.ehcache.Ehcache; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.util.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.Cache.ValueWrapper; /** * @author Yockii * */ public class EhCache<K, V> implements Cache<K, V> { private static final Logger log = LoggerFactory.getLogger(EhCache.class); private org.springframework.cache.Cache cache; public EhCache(org.springframework.cache.Cache cache) { if (cache == null) { throw new IllegalArgumentException("Cache argument cannot be null."); } this.cache = cache; } @Override public V get(K key) throws CacheException { try { if (log.isTraceEnabled()) { log.trace("Getting object from cache [" + cache.getName() + "] for key [" + key + "]"); } if (key == null) { return null; } else { ValueWrapper vw = cache.get(key); if (vw == null) { if (log.isTraceEnabled()) { log.trace("ValueWrapper for [" + key + "] is null."); } return null; } else { return (V) vw.get(); } } } catch (Throwable t) { throw new CacheException(t); } } @Override public V put(K key, V value) throws CacheException { if (log.isTraceEnabled()) { log.trace("Putting object in cache [" + cache.getName() + "] for key [" + key + "]"); } try { V previous = get(key); cache.put(key, value); return previous; } catch (Throwable t) { throw new CacheException(t); } } @Override public V remove(K key) throws CacheException { if (log.isTraceEnabled()) { log.trace("Removing object from cache [" + cache.getName() + "] for key [" + key + "]"); } try { V previous = get(key); cache.evict(key); return previous; } catch (Throwable t) { throw new CacheException(t); } } @Override public void clear() throws CacheException { if (log.isTraceEnabled()) { log.trace("Clearing all objects from cache [" + cache.getName() + "]"); } try { cache.clear(); } catch (Throwable t) { throw new CacheException(t); } } @Override public int size() { try { return ((Ehcache) cache.getNativeCache()).getSize(); } catch (Throwable t) { throw new CacheException(t); } } @Override public Set<K> keys() { try { Ehcache ehcache = (Ehcache) cache.getNativeCache(); @SuppressWarnings("unchecked") List<K> keys = ehcache.getKeys(); if (!CollectionUtils.isEmpty(keys)) { return Collections.unmodifiableSet(new LinkedHashSet<K>(keys)); } else { return Collections.emptySet(); } } catch (Throwable t) { throw new CacheException(t); } } @Override public Collection<V> values() { try { Ehcache ehcache = (Ehcache) cache.getNativeCache(); @SuppressWarnings("unchecked") List<K> keys = ehcache.getKeys(); if (!CollectionUtils.isEmpty(keys)) { List<V> values = new ArrayList<V>(keys.size()); for (K key : keys) { V value = get(key); if (value != null) { values.add(value); } } return Collections.unmodifiableList(values); } else { return Collections.emptyList(); } } catch (Throwable t) { throw new CacheException(t); } } public long getMemoryUsage() { try { return ((Ehcache) cache.getNativeCache()).calculateInMemorySize(); } catch (Throwable t) { return -1; } } public long getMemoryStoreSize() { try { return ((Ehcache) cache.getNativeCache()).getMemoryStoreSize(); } catch (Throwable t) { throw new CacheException(t); } } public long getDiskStoreSize() { try { return ((Ehcache) cache.getNativeCache()).getDiskStoreSize(); } catch (Throwable t) { throw new CacheException(t); } } public String toString() { return "EhCache [" + cache.getName() + "]"; } } |
然后再在spring配置文件中加入shiro的spring配置信息,可以参考之前的博客或者官方的spring联合部分
注意这里shiro部分缓存cacheManage使用上面Spring的cacheManager,而注入到shiro缓存中的类要使用上面的org.apache.shiro.cache.ehcacheSpring3_1.EhCacheManager
改造这样就应该可以了,暂时未验证!
发表评论
-
ehcache 缓存监听器的使用CacheEventListener
2012-09-24 14:33 7696ehcache通过配置,可以实现诸如,内容最长缓存时间,内容最 ... -
spring 3.1中的cache小结
2012-09-24 11:58 3985spring 3.1中有cache了,下面结合目前网上的一些资 ... -
spring Failed to convert property value of type [$Proxy10] to required type
2012-09-12 21:42 4807org.springframework.beans.facto ... -
关于Spring事务代理类型转换问题($ProxyXX cannot be cast to 类型)(
2012-09-12 21:38 4262二、解决方案 后来在网上搜了一下,这样的问题很多 ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2009-09-27 00:50 5020实现一个控制器ShirdrnController,如下所示: ... -
ClassPathXmlApplicationContext和FileSystemXmlApplicationContext的路径设置祥解
2009-09-19 10:24 3666package com.openv.spring; ... -
ClassPathXmlApplicationContext 和FileSystemXmlAppli
2009-06-24 12:45 1402ClassPathXmlApplicationContext ... -
PropertyPlaceholderConfigurer
2008-12-03 10:38 2597Spring的框架中为您提供了一个 BeanFactoryPo ... -
Spring MVC 入门 实例
2008-07-03 10:55 5710下面开始开发Spring MVC应用程序 (2)修改WEB- ... -
Spring MVC 配置
2008-07-03 09:38 2083一,配置分发器 DispatcherServlet 是Spri ... -
JdbcTemplate - 查询
2008-06-20 10:40 6821使用JdbcTemplate进行查询时,可以使用queryF ... -
转载]spring+hibernate架构中Dao访问数据库的几种方法
2008-06-20 10:28 7708spring+hibernate架构中Dao访问数据库的几种方 ... -
JdbcTemplate总结
2008-06-20 10:10 26741.您可以使用JdbcTemplate的execute()方法 ... -
//插入很多书(批量插入用法)jdbcTemplate
2008-06-20 10:09 6924//插入很多书(批量插入用法) public void in ... -
JdbcTemplate学习笔记
2008-06-20 09:16 19591、使用JdbcTemplate的execute()方法执行S ...
相关推荐
2.1 添加依赖:在项目pom.xml文件中,引入Spring Boot的Shiro Starter和Shiro的相关依赖,如`spring-boot-starter-shiro`、`shiro-redis-session-manager`等。 2.2 配置Shiro:创建一个`ShiroConfig`类,配置Shiro...
编写处理用户请求的Controller,使用Shiro的注解`@RequiresAuthentication`、`@RequiresRoles`和`@RequiresPermissions`进行权限控制。 ### 4. 实现细节 - **认证**:Shiro通过`Subject`对象进行用户认证,`...
在Controller方法上使用Shiro的注解,如`@RequiresAuthentication`、`@RequiresPermissions`等,实现基于注解的权限控制。 ```java @RestController @RequestMapping("/api") public class UserController { @...
- **3.3 集成Spring MVC**:介绍如何将Shiro与Spring MVC框架进行整合,实现基于注解的权限控制。 - **3.4 整合MyBatis**:通过示例演示如何在MyBatis中实现用户数据的增删改查操作,并与Shiro进行集成。 #### 四、...
这一章通常会通过一个具体的例子来展示如何在实际项目中使用Shiro。这包括了如何配置Shiro、实现登录认证、实现权限控制等。 ### 第十七章:OAuth2集成 #### 17.1 服务器端 OAuth2是一种开放标准授权协议,用于...
在 SpringBoot 应用中,可以通过 Shiro 提供的注解来控制方法或 URL 的访问权限。例如,使用 `@RequiresRoles` 和 `@RequiresPermissions` 注解限制只有特定角色或权限的用户才能访问。 ```java @RestController @...
- **Spring MVC简介及基本使用**:了解Spring MVC框架的基本概念和使用方法。 - **Spring MVC注解开发**:学习基于注解的控制器开发方式。 - **处理器映射和处理器适配器**:掌握处理器映射和适配器的工作原理。 - *...
系统应具备用户注册、登录功能,可能使用了Spring Security或Shiro等框架实现权限控制,确保数据的安全性。 5.2 账务管理 包括收支记录、预算设定、费用报销等功能,通过MyBatis与数据库交互,实现数据的增删改查...
* 提供拦截器组件(Jboot、Spring)在登录后调用RPC接口实现对权限信息的拦截,把用户的菜单、权限、基地、地块信息提取后整合到缓存中,内部调用使用方法或缓存获取,不再通过RPC调用获取 2. 系统架构 2.1 数据...