Shiro缓存使用Redis、Ehcache、自带的MpCache实现的三种方式实例
第一种:使用Redis做缓存,将数据存储到redis数据库中
第一步:在项目里面引入redis,配置文件如下:
配置文件:spring_shiro_redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<description>spring-redis-cache配置文件</description>
<!-- ###############################-Redis-########################################### -->
<!-- 配置redis和spring 的整合 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitMills}" />
<!-- <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> -->
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.masterHost}" />
<property name="port" value="${redis.masterPort}" />
<property name="timeout" value="${redis.timeout}" />
<property name="password" value="${redis.masterPassword}" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
<bean id="template" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 开启事务 -->
<property name="enableTransactionSupport" value="true" />
<!-- 序列化策略 推荐使用StringRedisSerializer -->
<!-- <property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property> -->
<!-- <property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property> -->
<!--<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property> -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
<!--spring cache-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"
c:redisOperations-ref="template">
<!-- 默认缓存10分钟 -->
<property name="defaultExpiration" value="600"/>
<property name="usePrefix" value="true"/>
<!-- cacheName 缓存超时配置,半小时,一小时,一天 -->
<property name="expires">
<map key-type="java.lang.String" value-type="java.lang.Long">
<entry key="halfHour" value="1800"/>
<entry key="hour" value="3600"/>
<entry key="oneDay" value="86400"/>
<!-- shiro cache keys 对缓存的配置 -->
<entry key="authorizationCache" value="1800"/>
<entry key="authenticationCache" value="1800"/>
<entry key="activeSessionCache" value="1800"/>
</map>
</property>
</bean>
<!-- cache注解,和spring-ehcache.xml中的只能使用一个 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
</beans>
redis的配置文件redis.properties:
#Reids config
#最大能够保持活动的对象数
redis.maxIdle=10
redis.maxTotal=100
#当池内没有返回对象时最大等待时间
redis.maxWaitMills=1000
#超时时间
redis.timeout=1000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#redis-master
redis.masterHost=192.168.206.128
redis.masterPort=6379
redis.masterPassword=1234
下面是spring-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true">
<description>Spring-shiro配置文件</description>
<!--配置安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--设置自定义Realm-->
<property name="realm" ref="myRealm"/>
<!--将缓存管理器,交给安全管理器-->
<property name="cacheManager" ref="shiroSpringCacheManager"/>
<!-- 记住密码管理 -->
<property name="rememberMeManager" ref="rememberMeManager"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!-- 自定义realm -->
<bean id = "myRealm" class="com.dzf.shiro.MyRealm">
<property name="cacheManager" ref="shiroSpringCacheManager"/>
<property name="credentialsMatcher" ref="myCredentialsMatcher"/>
<!-- 打开缓存 -->
<property name="cachingEnabled" value="true"/>
<!-- 打开身份认证缓存 -->
<property name="authenticationCachingEnabled" value="true"/>
<!-- 打开授权缓存 -->
<property name="authorizationCachingEnabled" value="true"/>
<!-- 缓存AuthenticationInfo信息的缓存名称 -->
<property name="authenticationCacheName" value="authenticationCache"/>
<!-- 缓存AuthorizationInfo信息的缓存名称 -->
<property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<!-- 配置自定义缓存管理器,中引入redis缓存管理器 -->
<bean id = "shiroSpringCacheManager" class="com.dzf.shiro.ShiroSpringCacheManager">
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 密码错误5次锁定半小时 -->
<bean id="myCredentialsMatcher" class="com.dzf.shiro.MyCredentialsMatcher">
<property name="cacheManager" ref="shiroSpringCacheManager"/>
<property name="limitCacheName" value="halfHour"/>
<property name="passwordHash" ref="passwordHash"/>
</bean>
<bean id = "passwordHash" class="com.dzf.shiro.PasswordHash">
<!-- 使用MD5 -->
<property name="hashAlgorithm" value="md5" />
<!-- 加密5次 -->
<property name="hashIterations" value="2"/>
</bean>
<!-- 记住密码Cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- cookie的名字 -->
<constructor-arg value="rememberMe"/>
<property name="httpOnly" value="true"/>
<!-- 7天,-->
<property name="maxAge" value="604800"/>
</bean>
<!-- sesisonCookie 设置 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- cookie的名字 -->
<constructor-arg value="sessionIdCookie"/>
<property name="httpOnly" value="true"/>
<!-- 30分钟 单位是秒-->
<property name="maxAge" value="1800"/>
</bean>
<!-- rememberMe管理器,cipherKey生成见{@code Base64Test.java} -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('5aaC5qKm5oqA5pyvAAAAAA==')}"/>
<property name="cookie" ref="rememberMeCookie"/>
</bean>
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- 设置全局会话超时时间 半小时 单位是毫秒-->
<property name="globalSessionTimeout" value="1800000"/>
<!-- url上带sessionId 默认为true -->
<property name="sessionIdUrlRewritingEnabled" value="false"/>
<property name="sessionIdCookie" ref="sessionIdCookie"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean> <!-- 会话DAO 用于会话的CRUD -->
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<!-- Session缓存名字,配置30分钟过期 -->
<property name="activeSessionsCacheName" value="activeSessionCache"/>
<property name="cacheManager" ref="shiroSpringCacheManager"/>
</bean>
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 安全管理器 -->
<property name="securityManager" ref="securityManager"/>
<!-- 默认的登陆访问url -->
<property name="loginUrl" value="/login.jsp"/>
<!-- 登陆成功后跳转的url -->
<!-- <property name="successUrl" value="/index.jsp"/> -->
<!-- 没有权限跳转的url -->
<property name="unauthorizedUrl" value="/unauth.jsp"/>
<property name="filterChainDefinitions">
<value>
<!--
anon 不需要认证
authc 需要认证
user 验证通过或RememberMe登录的都可以
-->
/commons/** = anon
/static/** = anon
/user/login = anon
/user/toLogin= anon
/user/register = anon
/register.jsp = anon
/** = authc
</value>
</property>
</bean> <!-- 静态注入,相当于调用SecurityUtils.setSecurityManager(securityManager) -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>
第二步:定义自己的CacheManager
package com.dzf.shiro; import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;
/**
* <p> 自定义cacheManage 扩张shiro里面的缓存 使用reids作缓存 </p>
* <description>
* 引入自己定义的CacheManager
* 关于CacheManager的配置文件在spring-redis-cache.xml中
* </description>
* @author xxxx
* @date 2018年2月3日
* @time 14:01:53
*/ public class ShiroSpringCacheManager implements CacheManager ,Destroyable{ private org.springframework.cache.CacheManager cacheManager; public org.springframework.cache.CacheManager getCacheManager() {
return cacheManager;
} public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {
this.cacheManager = cacheManager;
} @Override
public void destroy() throws Exception {
cacheManager = null;
} @Override
public <K, V> Cache<K, V> getCache(String name) {
if (name == null ){
return null;
}
return new ShiroSpringCache<K,V>(name,getCacheManager());
} }
定义自己实现的Cache,实现了Shiro包里的Cache
package com.dzf.shiro; import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager; import java.util.Collection;
import java.util.Set; /**
* <p> 自定义缓存 将数据存入到redis中 </p>
* @author xxx
* @date 2018年2月1日
* @time 22:32:11
* @param <K>
* @param <V>
*/
@SuppressWarnings("unchecked")
public class ShiroSpringCache<K,V> implements org.apache.shiro.cache.Cache<K, V>{
private static final Logger log = LoggerFactory.getLogger(ShiroSpringCache.class);
private CacheManager cacheManager;
private Cache cache;
// private RedisCache cache2;
public ShiroSpringCache(String name, CacheManager cacheManager) {
if(name==null || cacheManager==null){
throw new IllegalArgumentException("cacheManager or CacheName cannot be null.");
}
this.cacheManager = cacheManager;
//这里首先是从父类中获取这个cache,如果没有会创建一个redisCache,初始化这个redisCache的时候
//会设置它的过期时间如果没有配置过这个缓存的,那么默认的缓存时间是为0的,如果配置了,就会把配置的时间赋予给这个RedisCache
//如果从缓存的过期时间为0,就表示这个RedisCache不存在了,这个redisCache实现了spring中的cache
this.cache= cacheManager.getCache(name);
}
@Override
public V get(K key) throws CacheException {
log.info("从缓存中获取key为{}的缓存信息",key);
if(key == null){
return null;
}
ValueWrapper valueWrapper = cache.get(key);
if(valueWrapper==null){
return null;
}
return (V) valueWrapper.get();
} @Override
public V put(K key, V value) throws CacheException {
log.info("创建新的缓存,信息为:{}={}",key,value);
cache.put(key, value);
return get(key);
} @Override
public V remove(K key) throws CacheException {
log.info("干掉key为{}的缓存",key);
V v = get(key);
cache.evict(key);//干掉这个名字为key的缓存
return v;
} @Override
public void clear() throws CacheException {
log.info("清空所有的缓存");
cache.clear();
} @Override
public int size() {
return cacheManager.getCacheNames().size();
} /**
* 获取缓存中所的key值
*/
@Override
public Set<K> keys() {
return (Set<K>) cacheManager.getCacheNames();
} /**
* 获取缓存中所有的values值
*/
@Override
public Collection<V> values() {
return (Collection<V>) cache.get(cacheManager.getCacheNames()).get();
} @Override
public String toString() {
return "ShiroSpringCache [cache=" + cache + "]";
}
}
我来稍微解释下这个自定义ShiroSpringCache类中的CacheManager,这个是CacheManager其实就是RedisCacheManager,我们通过getter和setter注入过,RedisCacheManager是CacheManager的实现类.自己跟着源码看下去,一看就可以看的懂。
到此为止,使用redis做缓存,和spring的集成就完成了。注意:需要使用的缓存只需要在spring_shiro_redis.xml中配置就行了,放入缓存中的对象需要实现序列号接口
第二种:使用Ehcache做缓存,可以将数据存储到磁盘中,也可以存到内存中
同样需要配置文件:ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" dynamicConfig="false">
<diskStore path="java.io.tmpdir"/>
<!--授权信息缓存-->
<cache name="authorizationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
statistics="true">
</cache>
<!--身份信息缓存-->
<cache name="authenticationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
statistics="true">
</cache>
<!--session缓存-->
<cache name="activeSessionCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
statistics="true">
</cache> <!-- 缓存半小时 -->
<cache name="halfHour"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false" /> <!-- 缓存一小时 -->
<cache name="hour"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"
diskPersistent="false" /> <!-- 缓存一天 -->
<cache name="oneDay"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false"
diskPersistent="false" /> <!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
<defaultCache name="defaultCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="false"
maxElementsOnDisk="100000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/> </ehcache>
spring和ehcache集成的配置文件:spring_ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- Spring提供的基于的Ehcache实现的缓存管理器 -->
<!-- 如果有多个ehcacheManager要在bean加上p:shared="true" -->
<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcacheManager"/>
<property name="transactionAware" value="true"/>
</bean>
<!-- cache注解,和spring-redis.xml中的只能使用一个 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
</beans>
从redis切到ehcache,除了引入上面这两个配置文件,其他的基本没有要动的,当然需要在spring.xml中,将spring-ehcache.xml引进去就像这样:
<!--redis 和 ehcache 任选其一 -->
<import resource="spring-ehcache.xml"/>
<!--<import resource="spring-redis-cache.xml"/>-->
<import resource="spring-shiro.xml"/>
我想熟悉spring的小伙伴,这都看的懂吧,
这样我们就实现了从redis切到ehcache,需要格外注意的是,命名的规范性,各缓存的名字,各bean的id保持一致,切换才方便。
第三种:使用MemoryConstrainedCacheManager这个缓存管理器,将数据缓存到内存中去
解释:Shiro已经为我们编写了一套缓存的实现,那就是MpCache,是使用Map实现的,有兴趣的可以去看源码
怎么使用这个shiro已经为我们实现好的缓存,是非常容易的。
在上面的spring-shiro.xml中,我标红的这一句:
<bean id = "shiroSpringCacheManager" class="com.dzf.shiro.ShiroSpringCacheManager">
<property name="cacheManager" ref="cacheManager"/>
只需要把这个改为下面这句:
<!-- 配置shiro自带的缓存管理器 -->
<bean id = "shiroSpringCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>
就好了,对的,你没有看错,就是这么的简单。
好了,至此,三种实现都说完了,自己就自己的需求看,需要使用哪种级别的缓存吧。
Shiro缓存使用Redis、Ehcache、自带的MpCache实现的三种方式实例的更多相关文章
- SpringBoot中Shiro缓存使用Redis、Ehcache
在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...
- js setTimeout 传递带参数的函数的2种方式
js setTimeout 传递带参数的函数的2种方式 Created by Marydon on 2018年9月14日 1.准备工作 function sayYourName(param) { ...
- Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...
- PHP数组缓存:三种方式JSON、序列化和var_export的比较
使用PHP的站点系统,在面对大数据量的时候不得不引入缓存机制.有一种简单有效的办法是将PHP的对象缓存到文件里.下面我来对这3种缓存方法进行说明和比较. 第一种方法:JSONJSON缓存变量的方式主要 ...
- redis实现訪问频次限制的几种方式
结合上一篇文章<redis在学生抢房应用中的实践小结>中提及的用redis实现DDOS设计时遇到的expire的坑.事实上,redis官网中对incr命令的介绍中已经有关于怎样用redis ...
- 【Web前端Talk】“用数据说话,从埋点开始”-带你理解前端的三种埋点
埋点到底是什么呢? 引用自百科的原话是,埋点分析网站分析的一种常用的数据采集方法.因此其本质是分析,但是靠什么分析呢?靠埋点得到的数据.通俗来讲,就是当我想要在某个产品上得到用户的一些行为数据用来分析 ...
- Redis集群搭建的三种方式
一.Redis主从 1.1 Redis主从原理 和MySQL需要主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生性能瓶颈,特别是在读压力上,为了分担压力,Redis支持主从复制. ...
- redis集群的三种方式
Redis三种集群方式:主从复制,哨兵模式,Cluster集群. 主从复制 基本原理 当新建立一个从服务器时,从服务器将向主服务器发送SYNC命令,接收到SYNC命令后的主服务器会进行一次BGSAVE ...
- redis数据库服务器开启的三种方式
redis的启动方式1.直接启动 进入redis根目录,执行命令: #加上‘&’号使redis以后台程序方式运行 1 ./redis-server & 2.通过指定配置文件启动 ...
随机推荐
- Duilib教程-控件练习
一.控件消息的响应. 在HelloDuilib例子中,程序不能退出,在这里,我将添加一个关闭按钮,当点击它时,调用PostQuitMessage进行退出. 首先在界面的右上角添加一个关闭按钮,并取名为 ...
- 怎么查看mac系统是32位还是64位的操作系统
如何查看mac系统是32位还是64位的操作系统 (一)点击工具栏左上角点击 (苹果Logo)标志,关于本机 --> 更多信息 --> 系统报告 -->(左侧栏中)软件 (二) ...
- python 之 内置函数大全
一.罗列全部的内置函数 戳:https://docs.python.org/2/library/functions.html 二.range.xrange(迭代器) 无论是range()还是xrang ...
- Java模拟并发
=========================one============================= public class Bingfa { public static void m ...
- Java 语言基础之数组常见操作
对数组操作最基本的动作: 存和取 核心思想: 就是对角标的操作 数组常见操作: 1, 遍历 2, 获取最大值和最小值 3, 排序 4, 查找 5, 折半查找 // 1. 遍历 int[] arr = ...
- 初识idea
http://blog.csdn.net/bitcarmanlee/article/details/54951589 http://blog.csdn.net/haishu_zheng/article ...
- caffe自定义layer
caffe自带layers: http://caffe.berkeleyvision.org/tutorial/layers.html Layers: Image Data - read raw im ...
- 【POJ3615】Cow Hurdles 最短路,你若LCA,我仍不拦你。
NOIP2013货车运输.仅仅只是数据范围小了很多. 不到150s打完而且AC. . 额.当然.我写的是Floyd. 写LCA的真过分. #include <cstdio> #includ ...
- Touch事件分发机制
原文:http://www.cnblogs.com/linjzong/p/4191891.html Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实 ...
- pc端用微信扫一扫实现微信第三方登陆
官方文档链接 第一步:获取AppID AppSecret (微信开发平台申请PC端微信登陆) 第二步:生成扫描二维码,获取code https://open.weixin.qq.com/conn ...