`
longzhun
  • 浏览: 371596 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用Spring AOP处理自定义注解

 
阅读更多

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 {

......

}

能看出这两种方法之间的区别吗?

  • 大小: 63.4 KB
  • 大小: 14.3 KB
  • 大小: 10.8 KB
  • 大小: 55.5 KB
  • 大小: 26 KB
  • 大小: 23.8 KB
  • 大小: 77.8 KB
分享到:
评论

相关推荐

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    springAop+自定义注解实现权限管理

    一个简单的采用自定义注解结合SpringAop实现方法执行的权限管理,这个demo中并没有涉及到与数据库的交互和业务代码,用户权限在登陆时采用简单的手动初始化。该demo用的jdk1.7编译,Spring4.0版本,只想通过这个demo...

    详解使用Spring AOP和自定义注解进行参数检查

    使用Spring AOP和自定义注解进行参数检查 了解使用Spring AOP和自定义注解进行参数检查的技术细节。通过自定义注解和spring AOP,我们可以实现参数的校验,提高代码的可读性和可维护性。 自定义注解 在本篇文章中...

    spring aop+自定义注解+反射实现统一校验脚手架

    工程介绍:SpringBoot项目脚手架,利用spring aop+java反射实现自定义注解校验参数 源码里有使用都例子在DemoContorller example1:校验userName参数必填 @CheckParams(notNull = true) private String userName;...

    SpringMVC利用AOP实现自定义注解记录日志

    本篇将深入探讨如何利用AOP和自定义注解来实现日志记录功能。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了应用程序中的某个关注点,如日志。切面可以理解为一系列相互关联的方法和通知...

    spring中自定义注解(annotation)与AOP中获取注解

    本文将深入探讨如何在Spring中创建自定义注解以及如何在AOP中有效地获取并利用这些注解。 首先,自定义注解是Java语言提供的一种元数据机制,它允许我们在代码中添加额外的信息,而这些信息可以在编译时或运行时被...

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...

    详解使用Spring Boot的AOP处理自定义注解

    使用Spring Boot的AOP处理自定义注解 AOP(Aspect-Oriented Programming,面向切面编程)是一种程序设计范型,旨在解决横切关注点(crosscutting concern)的问题。Spring Boot提供了AOP的支持,使得开发者可以轻松...

    SpringBoot中的AOP+自定义注解(源代码)

    SpringBoot 中的 Aop + 自定义注解 1. @AspectJ 1.1 `@AspectJ` 切面类 1.2 `@Pointcut` 创建切入点 1.3 通知 1.4 Spring AOP 和 AspectJ AOP 有什么区别? 2. 在 SpringBoot 中使用 Aop 功能 2.0 创建一个...

    Spring 自定义注解的解析

    在Spring框架中,自定义注解的解析是一个强大的特性,允许开发者根据业务需求创建特定的注解,并在Spring容器启动时自动处理这些注解。本文将深入探讨如何在Spring环境中通过`component-scan`配置来处理自定义Java...

    SpringBoot AOP各种注解、自定义注解、鉴权使用案例(免费下载)

    自定义注解通常用于标记需要特殊处理的方法。例如,创建一个名为`@Cacheable`的自定义注解,用于缓存方法的返回结果: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface...

    java(spring boot)自定义注解

    总结来说,这个示例展示了如何在Spring Boot项目中自定义注解,将其应用于Java Bean的方法,以及如何利用AOP来实现全局扫描和自动执行。这样的实践在系统监控、性能分析和故障排查中非常有用,能够帮助开发者更好地...

    SpringBoot下的SpringAOP-day04-源代码

    SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法 1.动态代理总结 1.1 JDK动态代理特点 1.2 CGlib动态代理 1.2.1 CGLib特点说明 1.3 动态代理的作用 2 Spring...

    Spring AOP 自定义注解的实现代码

    在 Spring AOP 中,我们可以使用 AspectJ 来织入自定义注解,以便在方法执行前后执行相应的处理逻辑。例如: ```java &lt;aop:aspectj-autoproxy proxy-target-class="true"&gt; &lt;aop:include name="controllerAspect" /...

    spring自定义注解样例

    本示例主要探讨如何在Spring中创建和使用自定义注解,以及与AOP结合实现动态代理。 首先,我们需要了解自定义注解的基本结构。在Java中,自定义注解是以`@interface`关键字定义的。例如,我们可以创建一个名为`...

    spring AOP自定义注解方式实现日志管理的实例讲解

    Spring AOP 自定义注解方式实现日志管理的实例讲解 在本文中,我们将探讨如何使用 Spring AOP 实现日志管理,并使用自定义注解方式来记录日志信息。这种方式可以灵活地实现日志管理,提高系统的可维护性和可扩展性...

    SpringAOP的注解配置

    例如,`@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Loggable`,我们可以创建一个自定义注解`@Loggable`,然后在需要记录日志的方法上使用此注解。在切面中,...

    Spring Boot 通过AOP和自定义注解实现权限控制的方法

    Spring Boot 通过 AOP 和自定义注解实现权限控制的方法 在本文中,我们将探讨如何使用 Spring Boot 通过 Aspect-Oriented Programming(AOP)和自定义注解来实现权限控制。权限控制是任何应用程序的重要组件,它...

    spring aop 自定义切面示例

    总结一下,Spring AOP自定义切面结合AspectJ库,为我们提供了强大而灵活的代码组织方式。通过定义切面类和通知,我们可以轻松地将横切关注点与业务逻辑分离,提高代码的可维护性和复用性。同时,AspectJ的切入点...

    Java自定义注解与spring BeanPostProcessor详解

    通过查看Spring框架的源代码,我们可以看到BeanPostProcessor是如何被触发的,以及如何处理自定义注解。此外,对于自定义注解的处理,我们还可以参考Java编译器工具(如javac或现代IDE)如何处理注解处理器的代码。 ...

Global site tag (gtag.js) - Google Analytics