<p>import java.lang.annotation.*;<br/><br/>/<br/>&nbsp;* 元注解 用来标识查询数据库的方法<br/>&nbsp;*/<br/>@Documented<br/>@Target(ElementType.METHOD)<br/>@Retention(RetentionPolicy.RUNTIME)<br/>public @interface UseMemCache {<br/><br/>&nbsp;&nbsp; &nbsp;/<br/>&nbsp;&nbsp; &nbsp; * 缓存超时时间控制,&gt; 0 则做超时控制<br/>&nbsp;&nbsp; &nbsp; * @return<br/>&nbsp;&nbsp; &nbsp; */<br/>&nbsp;&nbsp; &nbsp;int expireSeconds() default 30;<br/>}</p><p>=================================================</p><p><br/></p><p><br/></p><p><br/></p><p><br/></p><p><br/></p><p><br/>/<br/>&nbsp;* AOP实现cache缓存处理(缓存到静态对象)<br/>&nbsp;* <br/>&nbsp;* @decr<br/>&nbsp;* @author jlchent<br/>&nbsp;* @date 2018年11月03日<br/>&nbsp;*<br/>&nbsp;*/<br/>@Component<br/>@Aspect<br/>public class MemCacheAspect {<br/><br/>&nbsp;&nbsp; &nbsp;private static final Logger logger = LoggerFactory.getLogger(MemCacheAspect.class);<br/><br/>&nbsp;&nbsp; &nbsp;/<br/>&nbsp;&nbsp; &nbsp; * 数据缓存<br/>&nbsp;&nbsp; &nbsp; */<br/>&nbsp;&nbsp; &nbsp;private&nbsp; static Hashtable&lt;String, Object&gt; dataTable = new Hashtable&lt;&gt;();<br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;/<br/>&nbsp;&nbsp; &nbsp; * 超时控制<br/>&nbsp;&nbsp; &nbsp; */<br/>&nbsp;&nbsp; &nbsp;private&nbsp; static Hashtable&lt;String, Long&gt; timeoutTable = new Hashtable&lt;&gt;();<br/><br/>&nbsp;&nbsp; &nbsp;<br/><br/>&nbsp;&nbsp; &nbsp;/<br/>&nbsp;&nbsp; &nbsp; * 拦截所有元注解cacheCache注解的方法<br/>&nbsp;&nbsp; &nbsp; */<br/>&nbsp;&nbsp; &nbsp;@Pointcut(&quot;@annotation(cn.com.framework.annotation.UseMemCache)&quot;)<br/>&nbsp;&nbsp; &nbsp;public void pointcutMethod() {<br/>&nbsp;&nbsp; &nbsp;}<br/><br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;private String saveObjToMem(String cacheKey, Object obj, int expireSeconds){<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dataTable.put(cacheKey, obj);<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Long expireTime = System.currentTimeMillis() + expireSeconds*1000;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;timeoutTable.put(cacheKey, expireTime);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return &quot;OK&quot;;<br/>&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;private String saveObjToMem(String cacheKey, Object obj){<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dataTable.put(cacheKey, obj);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return &quot;OK&quot;;<br/>&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;private Object getObjFromMem(String cacheKey) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Long expireTime = timeoutTable.get(cacheKey);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Long currentTime = System.currentTimeMillis();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (null != expireTime &amp;&amp; currentTime &gt; expireTime) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;过期清空<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dataTable.remove(cacheKey);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;timeoutTable.remove(cacheKey);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return null;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}else<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return dataTable.get(cacheKey);<br/>&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;/<br/>&nbsp;&nbsp; &nbsp; * 环绕处理,先从cache里获取缓存,查询不到,就通过method查询, 然后再保存到cache缓存里<br/>&nbsp;&nbsp; &nbsp; * <br/>&nbsp;&nbsp; &nbsp; * @param joinPoint<br/>&nbsp;&nbsp; &nbsp; * @return<br/>&nbsp;&nbsp; &nbsp; * @throws Throwable<br/>&nbsp;&nbsp; &nbsp; */<br/>&nbsp;&nbsp; &nbsp;@Around(&quot;pointcutMethod()&quot;)<br/>&nbsp;&nbsp; &nbsp;public Object around(ProceedingJoinPoint joinPoint) throws Throwable {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 前置:从cache里获取缓存<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 先获取目标方法参数<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;long startTime = System.currentTimeMillis();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Object[] args = joinPoint.getArgs();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String pragrm = &quot;&quot;;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (args != null &amp;&amp; args.length &gt; 0) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (int i = 0; i &lt; args.length; i++) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pragrm = &quot;_&quot;+pragrm + String.valueOf(args[i]) ;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 获取目标方法所在类<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String target = joinPoint.getTarget().toString();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String className = target.split(&quot;@&quot;)[0];<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 获取目标方法的方法名称<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String methodName = joinPoint.getSignature().getName();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int expireSeconds = 0;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;try {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Class&lt;?&gt; clz = Class.forName(className);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Class&lt;?&gt;[] classes = null;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (args != null &amp;&amp; args.length &gt; 0) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;classes = new Class[args.length];<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (int i = 0; i &lt; classes.length; i++) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;classes[i] = args[i].getClass();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Method method = clz.getMethod(methodName, classes);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;UseMemCache useMemCache = method.getAnnotation(UseMemCache.class);<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (useMemCache != null &amp;&amp; useMemCache.expireSeconds() &gt; 0) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;expireSeconds = useMemCache.expireSeconds();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} catch (ClassNotFoundException e1) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;e1.printStackTrace();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.warn(&quot;类包&quot;+className+&quot;不存在&quot;, e1);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;throw e1;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; cache中key格式: applId:方法名称<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String cacheKey =&nbsp; className + &quot;.&quot; + methodName + pragrm;<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Object obj =&nbsp; getObjFromMem(cacheKey);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (obj != null) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.debug(&quot;cache的VALUE值类型:&quot; + obj.getClass().getName());<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return obj;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;long endTime = System.currentTimeMillis();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.debug(&quot;cache缓存AOP处理所用时间(毫秒):&quot; + (endTime - startTime));<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;没有从cache查到数据&quot;);<br/><br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;开始通过Method查询数据&quot;);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;obj = joinPoint.proceed();<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (obj == null) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;获取到null数据&quot;);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return null;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 后置:将数据库查到的数据保存到cache<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String code = &quot;&quot;;<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (expireSeconds &gt; 0) {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;code = saveObjToMem(cacheKey, obj, expireSeconds);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} else {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;code = saveObjToMem(cacheKey, obj);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if &quot;OK&quot;).equals(code {<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;数据成功保存到cache缓存!!!**&quot;);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;MeM的KEY值:&quot; + cacheKey);<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;logger.info(&quot;cache的VALUE值类型:&quot; + obj.getClass().getName());<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br/>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return obj;<br/>&nbsp;&nbsp; &nbsp;}<br/><br/>}</p>