使用AspectJ注解技术实现AOP功能

AspectJ是一个面向切面编程的框架,使用AspectJ不需要改动Spring配置文件,就可以实现Spring AOP功能。本篇结合实际案例详细讲述使用AspectJ实现AOP功能。通过本篇的学习,可以解决如下问题。

● 使用AspectJ技术的背景是什么?

● 在不修改原有业务代码的情况下,如何设置业务拦截点?

 

1、 使用AspectJ技术的背景

 

在使用AspectJ之前,需要确定项目已经引入了AspectJ相关Jar包,并且AspectJ的版本要兼容JDK、Spring框架的版本,使用不兼容的版本会导致程序报错。

课程案例SpringProgram项目使用的JDK版本是1.8,Spring框架版本是5.08。需要引入的AspectJ相关Jar包如下所示。

● aspectj-1.8.9

● aspectjweaver-1.8.9

关于AOP实现原理在《详解Spring框架的AOP机制》一文中已经详细描述,这里不再赘述。不过本文的AOP项目案例还是借鉴《详解Spring框架的AOP机制》一文中的案例。因为Spring框架提供了AspectJ 注解方法和基于XML架构的方法来实现AOP,在《详解Spring框架的AOP机制》中,重点介绍了基于XML架构的方法来实现AOP,本文将重点介绍利用AspectJ 注解方法实现AOP。用同一个案例采用两种不同的实现方法,既可以加深对AOP的理解,也可以对两种实现技术进行对比,可以选择适合自己的一种技术来实现AOP。

在课程案例SpringProgram项目中,一个业务流程是校长通过邮件发送上课通知给老师。校长执行该业务时,业务系统并没有对老师进行验证。现在要求校长在发送通知之前,需要对老师进行用户验证。

具体要求是在尽量不改变原有业务代码的情况下,加入老师验证功能。原有业务代码如下。

 

分析上面的业务代码,可以考虑在执行setTeacher之前加入老师的验证方法,并将老师对象teacherZhang作为参数传给验证方法。如果能够修改业务代码,可以直接在setTeacher方法之前加入VerifyTeacher验证方法。

 

由于各种原因,不允许修改原有的业务代码。在这种情况下,可以采用AOP技术,拦截setTeacher方法,在setTeacher方法执行之前、执行之后、抛出异常之后执行拦截方法。拦截方法所在类的称为切面,拦截方法称为切入点。如下图所示。

 

图 1 使用AOP拦截setTeacher方法

2、使用Aspectj拦截setTeacher方法

 

AspectVerifyUser类用于验证老师身份,如果不加Aspecj注解,AspectVerifyUser类只是一个普通的Java类,不能被AOP调度使用。要使AspectVerifyUser类作为切面使用并拦截setTeacher方法,实现执行setTeacher方法之前先执行VerifyTeacher方法,在setTeacher方法执行成功后,再执行AfterSetTeacher方法。就需要在AspectVerifyUser类中添加Aspecj注解。

添加@Aspect注解

在类头部加@Aspect注解,使AspectVerifyUser类成为切面类,并被AOP识别和加载。作用类似于在Spring配置文件中的AOP标签<aop:config>。

添加 @Pointcut注解

在类方法头部加@Pointcut注解,使该方法称为一个切入点。@Pointcut注解的execution表达式定义该方法在什么位置切入。

例如:

 

@Pointcut注解指示AOP将VerifyUser()方法作为切入点,切入到AopEmailNotice类的setTeacher位置,传入的参数为任意类型和数量,VerifyUser()为空函数,实际执行的函数通过@Before、@After、@Around等注解与VerifyUser()方法关联。

再如:

 

@Pointcut注解指示AOP将VerifyUser()方法作为切入点,切入到com.milihua.springprogram.notice包及子包下所有的类及类中所有的方法。

又如:

 

@Pointcut注解指示AOP将VerifyUser()方法作为切入点,切入到com.milihua.springprogram.notice包下所有的类及类中所有的方法。

添加 @{ADVICE-NAME}注解

@{ADVICE-NAME}为声明建议注解,也可以称之为通知注解。该注解添加到实际执行函数的头部,并与切入点的名称进行关联。

@{ADVICE-NAME}有五种注解,分别是@Before、@After、@Around、@AfterReturning、@AfterThrowing。被@Before注解的方法在被切入方法执行之前执行;被@After注解的方法在被切入方法执行之后执行,不考虑是否执行成功;被@AfterReturning注解的方法在被切入方法执行成功之后执行,当被切入方法发生异常时,该方法不被执行;被@Around注解的方法在被切入方法执行之前和执行之后都执行;被@AfterThrowing注解的方法,只有当被切入方法执行过程发生异常时才会执行。

例如:

 

VerifyTeacher方法头部被@Before("VerifyUser()")注解,该方法在被切入的setTeacher方法之前执行。

 

获取通知参数

切入方法如何获取被切入方法传递过来的参数呢?例如,AspectVerifyUser类的VerifyTeacher方法切入到AopEmailNotice类的setTeacher方法,VerifyTeacher需要获取setTeacher方法的AopTeacher类参数,用于对老师进行用户验证。

AOP使用org.aspectj.lang.JoinPoint类型,用于获取被切入点传入的参数,任何切入方法的第一个参数都可以是JoinPoint。JoinPoint结构如下。

 

其中,getArgs方法可以获取被切入点方法参数列表,根据参数列表可以获取传入的参数。

在课程案例SpringProgram项目中,添加aspec.xml,配置AspectVerifyUser类。

 

在课程案例SpringProgram项目中,添加测试类。

 

 

课程小结

(1)本篇探讨了使用AspectJ技术的背景。当原有业务流程需要添加事务处理、安全控制、性能统计、异常处理等功能时,可以使用AspectJ技术在不修改原有业务代码的情况下,将上述功能切入到业务流程中;在构建新的系统时,也可以将上述功能独立考虑,再通过AspectJ技术将它们集成到系统中。

(2)本篇也通过案例讲述了应用AspectJ技术实现AOP的过程,具体实现步骤是:首先编写需要切入业务流程的独立模块(也称为切面)和切入点(模块中的方法),并添加AspectJ相关注解,确定切入的位置;然后在Spring配置文件中配置新添加的切面Bean,无需配置AOP信息;最后编写测试代码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用Spring的AOP可以实现缓存功能。具体实现方式是,在需要缓存的方法上添加@Cacheable注解,指定缓存的key和缓存的名称。当方法被调用时,Spring会先检查缓存中是否存在该key对应的缓存数据,如果存在则直接返回缓存数据,否则执行方法并将返回结果缓存起来。同时,还可以使用@CachePut注解更新缓存数据,或者使用@CacheEvict注解清除缓存数据。这样可以有效地提高系统性能和响应速度。 ### 回答2: 使用Spring的AOP实现缓存功能的步骤如下: 1. 首先,需要在Spring配置文件中启用AOP功能,可以通过添加`<aop:aspectj-autoproxy/>`来实现。 2. 然后,创建一个用于缓存方法调用结果的类,该类需要实现`org.springframework.cache.Cache`接口,并提供对缓存的读取、写入、删除等操作方法。 3. 还需要创建一个切面类,该类需要使用`@Aspect`注解进行标记,并在需要缓存的方法上添加`@Cacheable`注解。在切面类中,使用`@Before`和`@After`等注解来定义缓存操作的切点和通知。 4. 在Spring配置文件中,将切面类声明为一个bean,并在`<aop:config>`中指定要应用缓存的方法和切面。 5. 最后,配置`ehcache.xml`(或其他缓存配置文件),并将其指定为Spring配置文件中缓存管理器的实现类,例如`<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"/>`。 这样,当被缓存的方法被调用时,AOP将切入切面类的通知方法,首先查询缓存是否存在该方法的结果,如果存在,则直接返回缓存中的结果;如果不存在,则调用原始方法,并将结果存入缓存中。在后续的调用中,如果参数相同,则直接从缓存中获取结果,从而减少了对原始方法的调用,提高了系统的性能和响应速度。 使用Spring的AOP实现缓存功能可以大大简化代码,提高项目的可维护性和可扩展性,同时还能通过缓存数据减少对数据库等资源的访问,提升系统整体的性能。 ### 回答3: 使用Spring的AOP可以很方便地实现缓存功能AOP(面向切面编程)是一种编程范式,通过在程序运行时动态地将横切逻辑(如日志记录、事务管理、异常处理等)插入到应用程序的特定位置,以提供更好的代码结构和模块化。 在使用Spring的AOP实现缓存功能时,我们可以通过以下步骤来实现: 1. 定义一个缓存注解:可以使用Spring提供的@Cacheable注解来定义缓存的方法。这个注解可以应用在方法上,用于标记被缓存的方法。 2. 配置缓存切面:通过AOP切面配置,将缓存注解和具体的缓存实现关联起来。可以使用Spring的@Aspect注解来定义一个切面类,该类可以包含多个增强方法用于处理缓存操作。 3. 配置缓存策略:在切面类中,可以通过使用Spring的缓存管理器(如Ehcache、Redis等)来定义缓存的具体策略。可以配置缓存的过期时间、缓存的存储位置等。 4. 在目标方法中使用缓存注解:在需要被缓存的方法上添加之前定义的缓存注解。当方法被调用时,AOP切面会先检查缓存中是否存在对应的缓存数据,如果存在则直接返回缓存数据,否则执行方法逻辑并将结果存入缓存。 5. 测试缓存功能:执行目标方法,观察是否从缓存中获取数据以及方法执行的时间。 通过这种方式,我们可以很方便地在应用中加入缓存功能,提高系统性能和响应速度。同时,由于使用AOP的方式,可以很好地解耦和复用缓存相关的代码逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值