前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈AOP开发之开发Spring AOP程序

漫谈AOP开发之开发Spring AOP程序

作者头像
张张
发布2019-12-26 15:57:57
4970
发布2019-12-26 15:57:57
举报
文章被收录于专栏:前端全栈开发者

这是漫谈AOP系列的第三篇,前两篇请看

  1. 《漫谈AOP开发之初探AOP及AspectJ的用法》
  2. 《漫谈AOP开发之谈谈AOP那些学术概念 》

我们在Eclipse中创建一个新的工程,导入UserService、BookService两个类,并配置Spring的Bean:

代码语言:javascript
复制
<bean id="us" class="com.mybry.aop.service.UserService"/>
<bean id="bs" class="com.mybry.aop.service.BookService"/>

写一个增强处理类(Advice):

代码语言:javascript
复制
package com.mybry.aop.aspect;
public class AuthAspect {
    public void auth() {
        System.out.println("====执行权限检查的方法====");
    }
}

在前面的文章我们说过了,Spring AOP框架是在运行阶段动态生成AOP代理(在内存中动态地生成AOP代理类),以实现对目标对象的增强。它不需要特殊的编译器。所以不需要想AspectJ一样需要使用aspect声明类,这里直接用class即可。

接下来我们就在Spring中配置这个类:

代码语言:javascript
复制
<bean id="authAspect" class="com.mybry.aop.aspect.AuthAspect"/>

但此时Spring并知道这个类要作为Aspect使用的,这样依然只是一个普通的bean。还不知道要当肉来使用。这时候我们需要到如一个的明白空间AOP:

代码语言:javascript
复制
<beans xmlns="//www.springframework.org/schema/beans"
    xmlns:p="//www.springframework.org/schema/p"
    xmlns:aop="//www.springframework.org/schema/aop"
    xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="//www.springframework.org/schema/beans
    //www.springframework.org/schema/beans/spring-beans-3.2.xsd
    //www.springframework.org/schema/aop
    //www.springframework.org/schema/aop/spring-aop-3.2.xsd" >

所有有关AOP的配置,都放在aop:config元素中:

代码语言:javascript
复制
<aop:config>
    <!-- 将authAspect转换为Aspect 
	指定在执行com.mybry.aop.service包下任意类、返回值不限的任意方法之前,织入auth方法。
    -->
    <aop:aspect ref="authAspect">
       <aop:before method="auth" pointcut="execution(* com.mybry.aop.service.*.*(..))"/>
    </aop:aspect>
</aop:config>

AOP配置图:

注意,我们需要增加如下几个包:aopalliance、AspectJ、cglib。 运行上面的程序结果:

1、Spring支持的Advice 对于Advice而言,Spring一共支持5种Advice:

  • Before: 在方法执行之前。
  • AfterReturning: 只有成功返回后,才会织入该Advice
  • AfterThrowing: 只有抛出异常后,才会织入该Advice
  • After: 不管是抛出异常后,还是成功返回,都会织入该Advice
  • Around: 在目标方法执行之前、之后,都织入该Advice。

2、AOP编程步骤总结 (1) 写普通类,将打算作为Aspect用,并将该类配置在Spring容器中。 (2) 用aop:aspect将普通Bean,转换为Aspect, 需要指定ref属性,该属性指定将哪个Bean转换为Aspect。 (3) 在aop:aspect元素中配置:

  • aop:before.
  • aop:after-returning. 额外可指定returning,用于访问目标方法的返回值。该属性指定的参数值,还可用于对目标方法的返回值类型进行限制。如果不想对目标方法返回值类型进行限制,只要声明该参数类型为Object即可。
  • aop:after-throwing. 额外可指定throwing,用于访问目标方法的抛出的异常。该属性指定的参数值,还可用于对目标方法的抛出的异常类型进行限制。如果不想对目标方法抛出的异常类型类型进行限制,只要声明该参数类型为Exception即可
  • aop:after 功能有点类似finally块,通常用于回收资源。
  • aop:around, Advice方法,建议声明返回值,而且必须带一个ProceedingJoinPoint(AspectJ的API)类型的形参。

这5个元素,都可指定如下2个属性:

  • method:指定把哪个方法转为Advice。
  • pointcut|pointcut-ref:指定将Advice放到那些组件的哪些目标方法处。

3、Spring 的Advice的对比

动作

Befor

AfterReturning

AfterThrowing

After

Around

阻止方法执行

行(抛异常)

不行

不行

不行

访问调用参数

修改调用参数

不行

不行

不行

不行

访问返回值

不行

不行

不行

修改返回值

不行

不行

不行

不行

4、访问调用参数

借助于Pointcut形参:只要为Advice方法增加一个JoinPoint形参,即可通过该形参来访 目标的参数。

代码语言:javascript
复制
<!-- args切入点表达式,用于限制目标方法必须有N个参数  -->
<aop:before method="auth" pointcut="execution(* com.mybry.aop.service.*.*(..)) and args(arg0, arg1) "/>
代码语言:javascript
复制
public class AuthAspect{
    // 一旦在切入点表达式中使用args切入点表达式,即可在Advice方法中通过arg0、arg1来访问目标方法的调用参数
    public void auth(String arg0 , Object arg1){
	System.out.println("模拟进行权限检查");
	System.out.println("第1个参数为:" + arg0);
	System.out.println("第2个参数为:" + arg1);
    }
}
代码语言:javascript
复制
5、切入点表达式的写法简单介绍

	
execution([访问权限] [返回值类型] 包.类.方法(形参) [throws 异常]);

默认情况下,都可用*作为通配符。

形参列表支持2个通配符, ..代表任意个任意类型的参数; * 代表一个任意的参数。 (*, java.lang.String) 2个形参,且第二个形参必须是String (.., java.lang.String) 1~N个形参,最后一个形参必须是String

  • target(类型) ——要求目标对象指定类型。
  • this(类型) ——要求AOP代理对象指定类型。
  • args(a,b) —— 要求目标方法必须有匹配的形参。
  • bean(beanid) —— 专门为用Spring的菜鸟准备的。 只为特定Bean的方法织入增强处理。原生AspectJ并不支持,只有用Spring才支持。
代码语言:javascript
复制
<aop:config>
    <aop:pointcut expression="bean(us)" id="fkPc"/>
	<!-- 将authAspect转换为Aspect 
	指定在执行org.fkjava.aop.service包下任意类、返回值不限的任意方法之前,织入auth方法。
	-->
	<aop:aspect ref="authAspect">
	     <!-- args切入点表达式,用于限制目标方法必须有N个参数  -->
	     <aop:before method="auth" pointcut-ref="fkPc"/>	        
	</aop:aspect>
</aop:config>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档