Spring3.0中加入了对缓存的注解支持,即当你使用ehcache时可以使用例如@cachable等注解,这十分方便,省去了80%的缓存代码量(我自己感觉,因为自己操作缓存挺麻烦的)。
但是却遇到了一个问题,我的项目到时候需要tomcat集群部署,前端用F5做负载均衡,这样也就涉及到了缓存同步问题,虽然ehcache也有standalone server 、terracotta等技术来实现同步,但是至少我没能成功完成,总是有各种问题。
而且还有一个问题就是当集群部署的时候Java 中 synchronized 关键字失效,这就要求必须自己控制“锁”,以及锁的争用。于是我想到了用memcached比较适合,它的cas()也就是比较更新方法正好可以用于对锁获取时的控制。其实查看了一下ehcache的文档,它也有明确加锁模式,但是由于不参实现ehcache的单独部署,所以就采用memcached做缓存实现,client采用Xmemcached开发。
Xmemcached是不支持注解的,所以决定自己实现一下@cachable类似注解,其实核心也就是利用spring 的 aop技术对注解方法进行拦截加以处理。以下为简单示例。
在Maven中加入需要的包
这是我的maven文件片段,有一点要说的就是aspectj包,在maven仓库中搜索只能找到1.5.4版本,这个版本是不支持JDK5以上的版本的,如果使用JDK6的版本需要1.6.6以上的包,这个包的maven依赖关系可以在http://mvnrepository.com/这个网站找到。
在web.xml中加入spring支持,这个就不说了,在spring配置文件中打开aop功能
<aop:aspectj-autoproxy/>
之前要加上头文件声明 :
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
分别放到相应的位置。
建立自定义接口Young.java
建议一个使用这个注解的类YoungService.java
好多好多的中文或者英文资料讲述自定义注解的时候也就到此为止了,然后写一个测试所谓的处理器,把注解的类当成参数传到处理器中,然后使用java的反射机制判断某个方法是不是有注解,有的话怎样处理,这样手动调用处理器处理自定义注解,我如果要手动调用,我还要注解干嘛啊!我有手动调用那时间,我写一个静态方法实现同样的功能好不好啊!不知道这些资料到底是怎么样了!
下面说一下我写处理器的思路,只是个人思路,好不好不能保证。
我使用spring 的aop机制去拦截加了注解的方法,获取到传入方法的参数,判断方法是不是要去运行,如果运行再得到方法返回参数,加以处理再返回给调用该方法的类。
用到cache上也就是,我拦截得到了传入的key,判断我的memcached里面是不是已经有了值,如果有了值就不真正的执行方法了,将取出来的值返回给调用该方法的类就可以了,如果没有值那么就执行方法取得值,将取得的值存一份到memcached中,然后返回给调用该方法的类。这样就与spring自带的@cachable注解的功能一样了。那么就开始写这个处理器,其实灰常简单:
说一下这个类,从最上面说起,@Aspect是aspectj包中的注解,该注解并不会使spring自动扫描并且实例化该类,所以还必须加上@Complnent注解,当然spring配置文件中得打开自动扫描:<context:component-scan base-package="org.y0ung.example.custom_annotation_with_spring" />然后往下,@Around注解表明在切点方法的前后都要执行该处理器方法,那么切点在哪呢?切点就定义在了@Around后面的括号内也就是这个表达式:"execution (* org.y0ung.example.custom_annotation_with_spring.service.*.*(..)) && @annotation(young) && args(key)"这个表达式的意思是说指向这些方法,在org.y0ung.example.custom_annotation_with_spring.service包中的,所有类的(第一个*),所有方法(第二个*),并且该方法有注解@annotation(young)括号中的young是表示这个会做为参数传入处理器方法,也就是下面方法的第二个参数。而且这个方法还有一个参数args(key),并且这个key也做为参数传入到处理器方法。而ProceedingJoinPoint pjp参数是固有参数,你可以不加,但是要加一定要放到第一个位置。args(key)也可以不添加在@Around内,可以通过pjp.getArgs()方法获取传入参数。如果方法本来就有返回值,那么就要把上面的方法加上返回值Object,在方法中返回就可以了。
上面说了这么多好绕啊,要多看几遍才能看得懂。这些定义好了之后这个处理器基本就写完了,aroundYoung()方法内部就是利用那些传进来的参数做一些操作,如果需要执行目标方法则调用pjp.proceed()方法来调用。
以上只是一个简单示例,研究了两天才写出来的。
其实spring官方文档中还有一种注解的写法:
我我不知道为什么我像这样写始终都不能成功,也就是我那个方法上面的两行注释,所以只能按官方提供的第二种写法写
如果遇到的报错类似为:
error at ::0 can't find referenced pointcut anyPublicMethod
这种 错误,就是spring不能识别pointcut,可能表达式写错了。
网上一些资料说是aspectj版本太低了,我感觉应该不是,上面提到了,版本低了会报一个类似这样的错误:
error the @annotation pointcut expression is only supported at Java 5 compliance level or above
程序源代码请下载以下图片,下载后将后缀名改为rar解压即可直接导入eclipse
参考的文章中只有一往篇写得正确:http://zywang.iteye.com/blog/974226
再补充一下,关于Point Cut还有一种更灵活的写法
@Pointcut("execution (* org.y0ung.example.custom_annotation_with_spring.service.*.*(..))")
public void youngPointCut1(){}
我可以定义一个这样的注解,然后按这样调用
@Around("youngPointCut1() && @annotation(young) && args(key)")
public void aroundYoung(ProceedingJoinPoint pjp,Young young,String key) throws Throwable {
......
}
这样就可以实现灵活的控制不同参数,不同注解的各种方法。
当然也可以这样声明
@Pointcut("execution (* org.y0ung.example.custom_annotation_with_spring.service.*.*(..)) && @annotation(young) && args(key)")
public void youngPointCut(Young young,String key){}
这样调用
@Around("youngPointCut()")
public void aroundYoung(ProceedingJoinPoint pjp,Young young,String key) throws Throwable {
......
}
能看出这两种方法之间的区别吗?
相关推荐
Umi-OCR-main.zip
基于springboot+Web的毕业设计选题系统源码数据库文档.zip
基于springboot校外兼职教师考勤管理系统源码数据库文档.zip
58商铺全新UI试客试用平台网站源码
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于SpringBoot的口腔诊所系统源码数据库文档.zip
数据存放网盘,txt文件内包含下载链接及提取码,永久有效。失效会第一时间进行补充。样例数据及详细介绍参见文章:https://blog.csdn.net/T0620514/article/details/143956923
3-240P2162218.zip
网络安全 基于Qt创建的Linux系统下的浏览器.zip
C++ 类和对象:多态-练习题目2(制作咖啡和茶叶)
基于springboot+J2EE在线项目管理与任务分配中的应用源码数据库文档.zip
简介本项目提供了一个在51单片机上运行的简单操作系统,旨在帮助学习者深入理解操作系统的基本原理和任务调度机制。该操作系统通过汇编和C语言编写,实现了任务调度、中断处理等核心功能,并提供了详细的源代码和注释,方便学习和实践。
本文将深度卷积神经网络(CNN)设计实现一个复杂结构的生成模型,旨在通过多阶段的编码器-解码器结构,能够有效地将灰度图像转换为彩色图像。最后,本文将实现一个简单的Web应用,用户可以通过上传灰度图像,应用会使用预训练的Caffe模型对其进行颜色化,并将结果返回给用户。 1.模型设计:模型由多个卷积层、ReLU激活函数和批归一化层组成,通过前向传播函数将输入的灰度图像(L通道)转换为彩色图像(ab通道)。如果指定了 pretrained=True,则会自动下载并加载预训练的模型权重。 2. 系统通过Flask框架提供了一个Web应用,用户可以上传灰度图像,系统会自动将其转换为彩色图像,并在网页上显示结果。整个过程包括文件验证、图像处理、颜色化预测和结果展示,具有较高的实用性和用户体验。
一个JAVA图形化的、联网的五子棋游戏.zip javaweb
KWDB 是一款面向 【AIoT 场景】的【分布式多模数据库】,支持在同一实例同时建立时序库和关系库并融合处理多模数据,具备千万级设备接入、百万级数据秒级写入、亿级数据秒级读取等时序数据高效处理能力,具有稳定安全、高可用、易运维等特点。
页面数量:7页 网页主题:网站模板、酒店网站模板、官方网站模板 网页页面:首页、关于我们、相关服务、服务详情、在线博客、博客详情、在线留言 页面实现元素:加载动画、滚动加载、主题切换、导航栏 、轮播图、图文列表、图片切换、 文字列表、 按钮悬停、图片悬停、表单 实现技术:HTML、CSS 、JQuery 源码样式及js文件均分开存放,所有内容仅供初学者学习参考
内容概要:本文档提供了详细的 Neo4j 安装与配置指南,涵盖 Windows、Linux 和 Mac 系统的安装步骤。具体包括下载、安装、启动服务、修改配置文件(如端口配置、远程访问和内存限制)、设置管理员密码以及基本的 Cypher 查询语言使用方法。同时,还提供了一些常见问题及其解决方案。 适合人群:数据库管理员、软件开发人员、系统管理员。 使用场景及目标:①帮助初学者快速掌握 Neo4j 的安装与配置;②适用于需要搭建和使用图数据库的项目;③为已有用户解决常见问题。 其他说明:本文档不仅包含了基础的安装和配置流程,还提供了实际操作中可能遇到的问题及其解决方法,有助于提高使用者的实际操作能力。
基于SpringBoot+Vue的软件产品展示销售系统源码数据库文档.zip
《书戴嵩画牛》教学课件.pptx
20届智能车 【项目资源】:包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源,毕业设计等各种技术项目的源码。包括C++、Java、python、web、C#、EDA等项目的源码。 【适用人群】:适用于希望学习不同技术领域的初学者或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。