- 浏览: 269672 次
- 性别:
- 来自: 天津
文章分类
- 全部博客 (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 1097package com.gpcsoft.hct.epp.egp ... -
通过模板的方式解决缓存被击穿的问题
2019-04-15 11:35 4081. package gjp.tools; import c ... -
Rsa 加解密算法
2019-03-18 10:27 366package gjp.tools; /** * @Aut ... -
httpClient 使用http协议上传文件
2018-10-09 15:58 3102<dependency> <grou ... -
httpClient 使用HTTPS 协议上传文件
2018-09-30 14:50 2435<dependency> <group ... -
防止 XML外部实体注入
2018-09-18 17:03 7306方式一 DocumentBuilderFactory dbf ... -
httpClient 的https 调用
2018-06-20 21:07 807package com.gpcsoft.xjmodule.ut ... -
猎狗方式调用接口
2017-09-27 08:36 645package boce.hit.dog; import j ... -
netty 实现长连接
2017-08-24 09:52 13091.server 端信息 package com.boce.n ... -
netty 开发入门
2017-08-22 14:30 6671.准备jar <properties> & ... -
nio 编程实例
2017-08-16 14:15 5971.编写服务端 package com.boce.nio.s ... -
jwt 生成token 和解析token
2017-06-06 16:45 5914<jjwt.version>0.6.0</j ... -
实现Java高并发隔离 模拟
2017-05-08 10:34 513package org; import java.util. ... -
java 命令
2017-04-20 16:42 416java 命令: java -Djava.ext.dirs ... -
nio 通讯
2017-04-01 15:41 524nio 服务端: package nio.study.se ... -
HashMap 便利时不按照输入顺序输出
2017-03-27 17:11 1954使用:hashmap传输数据时,便利map中的数据时,发现 ... -
使用Lock,对不同商品加锁
2017-03-13 10:52 1247package com.boce.gbkutf; ... -
json 转泛型的集合类
2017-03-07 16:21 1212package com.boce.test; ... -
httpclient4.5 使用post方式提交请求
2017-03-03 11:00 2014private RequestConfig req ... -
GBK与UTF-8 字符串互转
2017-02-24 11:17 2206package 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(Aspect-Oriented Programming,面向方面编程)是一种编程技术,可以将散落在各个对象之间的逻辑提取出来,封装成一个个独立的模块,并将这些模块组合起来,形成一...
本文将深入探讨如何结合Spring AOP与EhCache实现一个简单的缓存实例,以便优化Java应用的运行效率。 首先,让我们了解Spring AOP。Spring AOP是Spring框架的一部分,它允许我们在不修改业务代码的情况下,通过定义...
本实例将介绍如何利用Spring AOP来实现自定义缓存功能。 首先,理解Spring AOP的基本概念。AOP是一种编程范式,它允许我们在不修改代码的情况下,为程序添加额外的功能,如日志记录、事务管理、安全检查等。在...
NULL 博文链接:https://zhang-yingjie-qq-com.iteye.com/blog/319927
SpringBoot集成Redis实现缓存处理(Spring AOP实现) 本文主要介绍了如何使用SpringBoot框架集成Redis实现缓存处理,通过Spring AOP(面向切面编程)实现缓存处理。下面是相关知识点的总结: 一、需求分析 在开源...
Spring AOP如何整合redis(注解方式)实现缓存统一管理详解 Spring AOP是Spring框架中的一种面向方面编程(AOP)的实现,它可以将横切关注点(Cross-Cutting Concerns)与业务逻辑进行分离,从而实现更加灵活和模块...
总之,Spring AOP通过代理技术实现了面向切面编程,使得开发者能够更专注于业务逻辑,而将通用的横切关注点剥离出来,提高了代码的可读性和可维护性。通过深入理解Spring AOP的实现机制,我们可以更好地利用这一强大...
在本篇【Spring AOP+ehCache简单缓存系统解决方案】中,我们将探讨如何利用Spring AOP(面向切面编程)和ehCache框架来构建一个高效、简单的缓存系统,以提升应用程序的性能。ehCache是一款流行的开源Java缓存库,它...
在本项目中,我们将探讨如何在SpringBoot中实现消息转换、切面编程(AOP)以及使用Redis作为缓存。 ### 消息转换 在SpringBoot中,消息转换是处理应用程序与外部系统之间数据交换的过程。Spring提供了`...
下面我们将深入探讨Spring AOP的概念、实现方式以及实际应用。 首先,我们需要理解AOP的基本概念。AOP是一种编程范式,它将关注点分离,使系统中的核心业务逻辑与辅助性任务(如日志、安全检查等)解耦。在Spring中...
4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于springboot+mvc+freemarker+aop实现校友信息管理系统源码.zip 基于springboot+mvc+freemarker+aop实现校友信息管理...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
总之,AOP通过提供一种新的角度来解决OO编程中存在的问题,使得我们能够在保持业务逻辑清晰的同时,增加额外的通用功能。利用Java反射机制和Spring AOP框架,开发者可以方便地实现AOP,从而提升代码的模块化和可维护...
在Java开发中,通过Spring框架可以方便地集成Redis,并利用AOP(面向切面编程)实现命令缓存,提升应用性能。本项目包含HashMap、List、Set、SortedSet以及String等多种Redis数据类型的命令操作。 首先,`pom.xml`...
在.NET平台上实现AOP,我们可以借助于不同的库和技术,如PostSharp、Unity、Autofac等。下面我们将深入探讨.NET平台AOP的实现方法和应用。 首先,我们需要理解AOP的基本概念。AOP的核心是切面(Aspect),它封装了...
越来越觉得的缓存是计算机科学里最NB的发明(没有之一),本文就来介绍了一下在Python中使用AOP实现Redis缓存示例,小伙伴们一起来了解一下 import redis enable=True #enable=False def readRedis(key): if enable: ...
在Java开发中,Spring AOP(面向切面编程)是一个强大的功能,用于实现日志记录。AOP允许我们在不修改原有代码的情况下,插入新的行为,比如日志记录,事务管理等。下面将详细介绍如何在Spring框架中使用AOP来实现...