- 浏览: 262392 次
- 性别:
- 来自: 天津
文章分类
- 全部博客 (183)
- oracle (4)
- informix (1)
- web开发 (6)
- java (49)
- hibernate (1)
- hadoop (1)
- spring (23)
- 非技术 (8)
- ibatis2 (5)
- Linux (6)
- tomcat (14)
- nginx (7)
- dubbo (3)
- myibatis (7)
- webservice 开发 (2)
- mysql (2)
- svn (2)
- redis (7)
- 分布式技术 (17)
- zookeeper (2)
- kafka (2)
- velocity (1)
- maven (7)
- js (1)
- freemarker (1)
- Thymeleaf (3)
- 代码审计 (1)
- ibatis3 (1)
- rabbitmq (1)
最新评论
实现代码在附件中
1.自定义注解文件
package sgnctest.el;
import java.lang.annotation.*;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyCache {
//key 值
String key() default "";
//缓存前缀
String preName() default "lypt";
//超时时间
long outTime() default 60000;
}
2.实现类
package sgnctest.el.service;
import org.springframework.stereotype.Service;
import sgnctest.el.MyCache;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Service
public class ServiceCacheInf{
@MyCache(key="#key")
public String getName(String key) {
System.out.println("====访问数据库"+key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return key;
}
}
3.建立aop 类
package sgnctest.el.service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import sgnctest.el.MyCache;
import sgnctest.el.Spel;
import sgnctest.el.util.LockServer;
import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Author by gjp, Date on 2019/9/16.
* aop 操作
*/
@Aspect
@Component
public class CacheAop {
@Resource
private RedisCache redisCache;
ThreadLocal<Long> startTime = new ThreadLocal<>();
// 定义需要匹配的切点表达式,同时需要匹配参数
@Around("@annotation(cache)")
public Object around(ProceedingJoinPoint pjp, MyCache cache) throws Throwable {
System.out.println("方法环绕start...around");
String key = cache.key();
String preName = cache.preName();
long timeOut = cache.outTime();
Object result = null;
String keyVal ="";
try {
// System.out.println("key:" + key + ";preName=" + preName + ";timeOut=" + timeOut);
MethodSignature signature = (MethodSignature) pjp.getSignature();
String[] parameters = signature.getParameterNames();
//jdk1.8
//Method method = signature.getMethod();
// Parameter[] parameters = method.getParameters();
Object obj[] = pjp.getArgs();
//通过el表达式获取值
keyVal = Spel.el(key, parameters, obj);
//从缓存中读取数据
result = redisCache.getCacheById(keyVal);
if(null != result){
return result;
}
//先加锁,然后从数据库中获取数据,从数据库中获取
LockServer.getInstance().doLock(keyVal);
result = redisCache.getCacheById(keyVal);
if(null != result){
return result;
}
result = pjp.proceed(); //pjp.proceed().toString() + "aop String keyVal:"+keyVal;
//加入缓存
redisCache.putCacheById(keyVal,result);
} catch (Throwable e) {
e.printStackTrace();
}finally {
LockServer.getInstance().releaseLock(keyVal);
}
// System.out.println("方法环绕end...around");
return result;
}
}
4.模拟缓存类
package sgnctest.el.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
* Author by gjp, Date on 2019/9/16.
* 从缓存中获取数据
*/
@Service
public class RedisCache {
private String keys="";
public Object getCacheById(String key){
if(StringUtils.isEmpty(keys)){
return null;
}
return "cache"+keys;
}
public void putCacheById(String key,Object object){
System.out.println("加入缓存"+key);
keys =key;
}
}
5.配置类
package sgnctest.el;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Configuration
@ComponentScan("sgnctest.el.service")
@EnableAspectJAutoProxy //开启Spring对AspectJ代理的支持
public class AopConfig {
}
6.el表达式(技术核心)
package sgnctest.el;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* Author by gjp, Date on 2019/9/16.
*/
public class Spel {
private static ExpressionParser parser = new SpelExpressionParser();
/**
* el表达式解析
* @param key 需要转换的el表达式
* @param parameters 变量名称
* @param args 变量值
* @return
*/
public static String el(String key,String[] parameters,Object[] args){
//key 解析为el表达式
Expression exp = parser.parseExpression(key);
EvaluationContext context = new StandardEvaluationContext();
if(null == args || args.length==0){
return null;
}
int len = args.length;
for(int i=0;i<len;i++) {
//参数和值防止上下文中
context.setVariable(parameters[i],args[i]);
}
//获取el中的参数值
return exp.getValue(context,String.class);
}
public static void main(String[] args) {
Spel spel = new Spel();
String key ="#ztb+' '+#pay";
String [] parameter = {"ztb","pay"};
Object [] obj ={"ztb123","pay123"};
System.out.println("result ::"+spel.el(key,parameter,obj));
}
}
7.测试类:
package sgnctest.el;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import sgnctest.el.service.ServiceCacheInf;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Author by gjp, Date on 2019/9/16.
*
* 测试类
*/
public class SpringMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AopConfig.class);
final ServiceCacheInf demoAnnotationService = context.getBean(ServiceCacheInf.class);
ExecutorService executor = Executors.newFixedThreadPool(10);
int callTime = 20;
final CountDownLatch countDownLatch = new CountDownLatch(callTime);
//模拟并发情况下的接口调用统计
for(int i=0;i<callTime;i++){
final int count =i;
executor.execute(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count%3 ==0) {
System.out.println(demoAnnotationService.getName("123456"));
}else if(count %3 ==1){
System.out.println(demoAnnotationService.getName("666"));
}else {
System.out.println(demoAnnotationService.getName("7775"));
}
}
});
countDownLatch.countDown();
}
executor.shutdown();
//等待所有线程统计完成后输出调用次数
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
context.close();
}
}
日志:
main 2019-09-16 14:52:27.765 [main] INFO org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
====访问数据库123456
====访问数据库7775
====访问数据库666
加入缓存666
加入缓存123456
加入缓存7775
cache123456
cache123456
cache123456
方法环绕start...around
cache666
666
123456
方法环绕start...around
方法环绕start...around
cache7775
方法环绕start...around
方法环绕start...around
cache7775
cache7775
cache7775
方法环绕start...around
cache7775
7775
cache7775
方法环绕start...around
方法环绕start...around
cache7775
cache7775
方法环绕start...around
cache7775
cache7775
方法环绕start...around
cache7775
cache7775
cache7775
1.自定义注解文件
package sgnctest.el;
import java.lang.annotation.*;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyCache {
//key 值
String key() default "";
//缓存前缀
String preName() default "lypt";
//超时时间
long outTime() default 60000;
}
2.实现类
package sgnctest.el.service;
import org.springframework.stereotype.Service;
import sgnctest.el.MyCache;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Service
public class ServiceCacheInf{
@MyCache(key="#key")
public String getName(String key) {
System.out.println("====访问数据库"+key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return key;
}
}
3.建立aop 类
package sgnctest.el.service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import sgnctest.el.MyCache;
import sgnctest.el.Spel;
import sgnctest.el.util.LockServer;
import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Author by gjp, Date on 2019/9/16.
* aop 操作
*/
@Aspect
@Component
public class CacheAop {
@Resource
private RedisCache redisCache;
ThreadLocal<Long> startTime = new ThreadLocal<>();
// 定义需要匹配的切点表达式,同时需要匹配参数
@Around("@annotation(cache)")
public Object around(ProceedingJoinPoint pjp, MyCache cache) throws Throwable {
System.out.println("方法环绕start...around");
String key = cache.key();
String preName = cache.preName();
long timeOut = cache.outTime();
Object result = null;
String keyVal ="";
try {
// System.out.println("key:" + key + ";preName=" + preName + ";timeOut=" + timeOut);
MethodSignature signature = (MethodSignature) pjp.getSignature();
String[] parameters = signature.getParameterNames();
//jdk1.8
//Method method = signature.getMethod();
// Parameter[] parameters = method.getParameters();
Object obj[] = pjp.getArgs();
//通过el表达式获取值
keyVal = Spel.el(key, parameters, obj);
//从缓存中读取数据
result = redisCache.getCacheById(keyVal);
if(null != result){
return result;
}
//先加锁,然后从数据库中获取数据,从数据库中获取
LockServer.getInstance().doLock(keyVal);
result = redisCache.getCacheById(keyVal);
if(null != result){
return result;
}
result = pjp.proceed(); //pjp.proceed().toString() + "aop String keyVal:"+keyVal;
//加入缓存
redisCache.putCacheById(keyVal,result);
} catch (Throwable e) {
e.printStackTrace();
}finally {
LockServer.getInstance().releaseLock(keyVal);
}
// System.out.println("方法环绕end...around");
return result;
}
}
4.模拟缓存类
package sgnctest.el.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
* Author by gjp, Date on 2019/9/16.
* 从缓存中获取数据
*/
@Service
public class RedisCache {
private String keys="";
public Object getCacheById(String key){
if(StringUtils.isEmpty(keys)){
return null;
}
return "cache"+keys;
}
public void putCacheById(String key,Object object){
System.out.println("加入缓存"+key);
keys =key;
}
}
5.配置类
package sgnctest.el;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Author by gjp, Date on 2019/9/16.
*/
@Configuration
@ComponentScan("sgnctest.el.service")
@EnableAspectJAutoProxy //开启Spring对AspectJ代理的支持
public class AopConfig {
}
6.el表达式(技术核心)
package sgnctest.el;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* Author by gjp, Date on 2019/9/16.
*/
public class Spel {
private static ExpressionParser parser = new SpelExpressionParser();
/**
* el表达式解析
* @param key 需要转换的el表达式
* @param parameters 变量名称
* @param args 变量值
* @return
*/
public static String el(String key,String[] parameters,Object[] args){
//key 解析为el表达式
Expression exp = parser.parseExpression(key);
EvaluationContext context = new StandardEvaluationContext();
if(null == args || args.length==0){
return null;
}
int len = args.length;
for(int i=0;i<len;i++) {
//参数和值防止上下文中
context.setVariable(parameters[i],args[i]);
}
//获取el中的参数值
return exp.getValue(context,String.class);
}
public static void main(String[] args) {
Spel spel = new Spel();
String key ="#ztb+' '+#pay";
String [] parameter = {"ztb","pay"};
Object [] obj ={"ztb123","pay123"};
System.out.println("result ::"+spel.el(key,parameter,obj));
}
}
7.测试类:
package sgnctest.el;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import sgnctest.el.service.ServiceCacheInf;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Author by gjp, Date on 2019/9/16.
*
* 测试类
*/
public class SpringMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AopConfig.class);
final ServiceCacheInf demoAnnotationService = context.getBean(ServiceCacheInf.class);
ExecutorService executor = Executors.newFixedThreadPool(10);
int callTime = 20;
final CountDownLatch countDownLatch = new CountDownLatch(callTime);
//模拟并发情况下的接口调用统计
for(int i=0;i<callTime;i++){
final int count =i;
executor.execute(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count%3 ==0) {
System.out.println(demoAnnotationService.getName("123456"));
}else if(count %3 ==1){
System.out.println(demoAnnotationService.getName("666"));
}else {
System.out.println(demoAnnotationService.getName("7775"));
}
}
});
countDownLatch.countDown();
}
executor.shutdown();
//等待所有线程统计完成后输出调用次数
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
context.close();
}
}
日志:
main 2019-09-16 14:52:27.765 [main] INFO org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
方法环绕start...around
====访问数据库123456
====访问数据库7775
====访问数据库666
加入缓存666
加入缓存123456
加入缓存7775
cache123456
cache123456
cache123456
方法环绕start...around
cache666
666
123456
方法环绕start...around
方法环绕start...around
cache7775
方法环绕start...around
方法环绕start...around
cache7775
cache7775
cache7775
方法环绕start...around
cache7775
7775
cache7775
方法环绕start...around
方法环绕start...around
cache7775
cache7775
方法环绕start...around
cache7775
cache7775
方法环绕start...around
cache7775
cache7775
cache7775
- el.zip (6.6 KB)
- 下载次数: 1
发表评论
-
统计多线程下程序运行总时间
2019-05-15 16:55 1031package com.gpcsoft.hct.epp.egp ... -
通过模板的方式解决缓存被击穿的问题
2019-04-15 11:35 3751. package gjp.tools; import c ... -
Rsa 加解密算法
2019-03-18 10:27 330package gjp.tools; /** * @Aut ... -
httpClient 使用http协议上传文件
2018-10-09 15:58 3061<dependency> <grou ... -
httpClient 使用HTTPS 协议上传文件
2018-09-30 14:50 2359<dependency> <group ... -
防止 XML外部实体注入
2018-09-18 17:03 7076方式一 DocumentBuilderFactory dbf ... -
httpClient 的https 调用
2018-06-20 21:07 738package com.gpcsoft.xjmodule.ut ... -
猎狗方式调用接口
2017-09-27 08:36 601package boce.hit.dog; import j ... -
netty 实现长连接
2017-08-24 09:52 12701.server 端信息 package com.boce.n ... -
netty 开发入门
2017-08-22 14:30 6401.准备jar <properties> & ... -
nio 编程实例
2017-08-16 14:15 5721.编写服务端 package com.boce.nio.s ... -
jwt 生成token 和解析token
2017-06-06 16:45 5872<jjwt.version>0.6.0</j ... -
实现Java高并发隔离 模拟
2017-05-08 10:34 476package org; import java.util. ... -
java 命令
2017-04-20 16:42 354java 命令: java -Djava.ext.dirs ... -
nio 通讯
2017-04-01 15:41 490nio 服务端: package nio.study.se ... -
HashMap 便利时不按照输入顺序输出
2017-03-27 17:11 1906使用:hashmap传输数据时,便利map中的数据时,发现 ... -
使用Lock,对不同商品加锁
2017-03-13 10:52 1218package com.boce.gbkutf; ... -
json 转泛型的集合类
2017-03-07 16:21 1186package com.boce.test; ... -
httpclient4.5 使用post方式提交请求
2017-03-03 11:00 1963private RequestConfig req ... -
GBK与UTF-8 字符串互转
2017-02-24 11:17 2148package com.cloud.tools; i ...
相关推荐
在net core2.2时,我当时就尝试过用autofac实现aop,但这次我不想用autofac,我用了一个更轻量级的框架,AspectCore。 用起来非常非常的简单,但一开始还是走了一点弯路,主要是网上都是net core3以下的教程,3以下...
本代码通过使用spring aop+ehcache的技术,实现了方法级别的查询缓存,主要原理是 方法的完整路径+方法参数值,作为key,放入cache中,下次访问时先判断cache中是否有该key.
主要介绍了Spring AOP实现Redis缓存数据库查询的相关内容,源码部分还是不错的,需要的朋友可以参考下。
基于Spring的AOP快速实现通用日志打印(csdn)————程序
spring aop 自定义缓存实现的一个小实例,地址:http://blog.csdn.net/maoyeqiu/article/details/50260357
NULL 博文链接:https://zhang-yingjie-qq-com.iteye.com/blog/319927
java springAOP实现数据字典
springboot实现消息转换、切面AOP和Redis缓存,实现相关技术的实例,以及相关方法的使用说明
NULL 博文链接:https://honda418.iteye.com/blog/354945
4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于springboot+mvc+freemarker+aop实现校友信息管理系统源码.zip 基于springboot+mvc+freemarker+aop实现校友信息管理...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
通过SpringAop实现多数据源的动态切换 并采用Druid连接池,可扩展继续增加数据库配置。
本篇文章主要介绍了在Python中使用AOP实现Redis缓存示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
演示了spring基于AOP代理TransactionProxyFactoryBean实现事务
spring作为一个aop框架,能轻松实现面向切面编程,本例演示如何使用spring进行面向切面编程。
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...
注解方式实现AOP编程
基于AOP编织技术的缓存框架研究和实现.caj 做毕业论文参考
基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker...