范例:定义一个参数拦截

package com.Spring.aop;

import org.springframework.stereotype.Component;

@Component
public class ServiceAspect { public void serviceBefore()
{
System.out.println("AOP切面执行日志记录操作");
} public void serviceBefore2(Object arg)
{
System.out.println("AOP切面执行增加前操作,参数="+arg);
}
public void serviceAfter()
{
System.out.println("AOP切面执行事务处理操作");
}
}

配置也修改:

<aop:config>
<!-- 定义程序的切入点 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
<aop:before method="serviceBefore2" pointcut-ref="pointcut"/>
<aop:after method="serviceAfter" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>

此时运行报错。

此时serviceBefore2方法有参数了,就需要修改了。

范例:定义切入点表达式

这里通过 and args()  和arg-names来指定要传入操作前方法的参数。

    <aop:config>
<!-- 定义程序的切入点 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
<aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
<aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>

运行结果:

因为after方法没有参数,不能直接使用第一个定义的切入点,所以这里after方法重新指定一个切入点,

而before是有参数的,直接使用第一个定义的切入点就行了。

除了操作之前拦截,也可以针对返回的结果进行拦截。

范例:针对返回结果拦截

package com.Spring.aop;

import org.springframework.stereotype.Component;

@Component
public class ServiceAspect { public void serviceBefore()
{
System.out.println("AOP切面执行日志记录操作");
} public void serviceBefore2(Object arg)
{
System.out.println("AOP切面执行增加前操作,参数=" +arg);
}
public void serviceAfter()
{
System.out.println("AOP切面执行事务处理操作");
}
public void serviceAfterReturn(Object val) //表示操作结果
{
System.out.println("AOP切面操作完成,返回结果:"+val);
}
}

配置里面修改:

    <aop:config>
<!-- 定义程序的切入点 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
<aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
<aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
<aop:after-returning method="serviceAfterReturn" pointcut="execution(* com.Spring..*.*(..)))" returning="haha" arg-names="haha"/>
</aop:aspect>
</aop:config>

这里通过returning和arg-names来传递返回结果给操作完成后返回方法:serviceAfterReturn,做完这个方法的参数。

执行结果:

除了返回结果的拦截之外,还能进行异常处理的拦截操作。

范例:修改MemberServiceImpl

package com.Spring.Test;

import org.apache.commons.lang.NullArgumentException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Spring.Service.IMemberService;
import com.Spring.Service.Impl.MemberServiceImpl;
import com.Spring.Vo.Member; public class TestMemberService { public static void main(String args[])
{
throw new NullArgumentException("我来抛出一个异常");
/*
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
IMemberService ser=ctx.getBean("memberServiceImpl",MemberServiceImpl.class);
Member vo=new Member();
vo.setMid("hello");
vo.setName("你好");
System.out.println(ser.insert(vo));
*/
}
}

增加拦截处理操作

package com.Spring.aop;

import org.springframework.stereotype.Component;

@Component
public class ServiceAspect { public void serviceBefore()
{
System.out.println("AOP切面执行日志记录操作");
} public void serviceBefore2(Object arg)
{
System.out.println("AOP切面执行增加前操作,参数=" +arg);
}
public void serviceAfter()
{
System.out.println("AOP切面执行事务处理操作");
}
public void serviceAfterReturn(Object val) //表示操作结果
{
System.out.println("AOP切面操作完成,返回结果:"+val);
} public void serviceAfterThrow(Exception e) //表示操作结果
{
System.out.println("AOP切面操作出现异常:"+
e);
}

}

配置:

    <aop:config>
<!-- 定义程序的切入点 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
<aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
<aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
<aop:after-returning method="serviceAfterReturn" pointcut="execution(* com.Spring..*.*(..)))" returning="haha" arg-names="haha"/>
<aop:after-throwing method="serviceAfterThrow" pointcut="execution(* com.Spring..*.*(..)))" arg-names="e" throwing="abc"/>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>

这里因为需要传递异常参数,所以需要arg-names和throwing,但是这两个的值随便写就像了,不用想对应起来。

运行结果:

以上几个拦截器已经可以处理AOP可以处理的范畴。但是为了简化,整个AOP还提供环绕通知,

即一个方法可以处理所有的aop操作,这种操作更像代理结构:

范例:增加环绕处理

但是必须考虑接收参数的情况,而接收的参数类型只能是一种类型:ProceedingJoinPoint,通过此类型可以取得全部的提交参数信息。

    public Object serviceAround(ProceedingJoinPoint point) throws Throwable
{
System.out.println("AOP切面数据层方法调用之前,参数:"+Arrays.toString(point.getArgs()));
Member vo=new Member();
vo.setMid("TestAOP");
vo.setName("测试AOP");
Object retVal=point.proceed(new Object[]{ vo });  //retVal接收方法数据层调用之后的结果
System.out.println("AOP切面数据层方法调用之后,返回值:"+retVal);
return true;
}

在整个环绕拦截之中,用户可以任意修改传递的参数数据,也可以修改返回的结果。

配置环绕拦截:

<aop:around method="serviceAround" pointcut="execution(* com.Spring..*.*(..)))" />

执行结果:

所以,在所有AOP操作中,环绕的功能是最强大的。其他拦截只能做一些信息记录,而环绕可以对传入的参数和返回结果进行控制。

18-spring学习-AOP深入操作的更多相关文章

  1. Spring Boot AOP 简易操作日志管理

    AOP (Aspect Oriented Programming) 面向切面编程. 业务有核心业务和边缘业务. 比如用户管理,菜单管理,权限管理,这些都属于核心业务. 比如日志管理,操作记录管理,这些 ...

  2. [原创]java WEB学习笔记107:Spring学习---AOP切面的优先级,重用切点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. spring 学习 AOP和IOC

    自11开始接触三大框架,至今已俞5载, 当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了 spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转) 1.其中, ...

  7. spring学习之三 数据库操作jdbcTemplate

    概念 jdbcTemplate就Spring对数据库持久化技术的实现,通过它可以对数据库进行CRUD等操作. JDBCTemplate和代码实现 public void jdbcadd() { Dri ...

  8. Spring学习-- AOP入门动态代理

    AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...

  9. 黑马Spring学习 AOP XML和注解配置 5种通知 切点切面通知织入

    业务类 package cn.itcast.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoin ...

随机推荐

  1. hdu 3586 树形dp+二分

    题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限lim ...

  2. Java并发(十四):并发工具类——CountDownLatch

    先做总结: 1.CountDownLatch 是什么? CountDownLatch 允许一个或多个线程等待其他线程(不一定是线程,某个操作)完成之后再执行. CountDownLatch的构造函数接 ...

  3. [bzoj1017][JSOI2008]魔兽地图 DotR (Tree DP)【有待优化】

    Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...

  4. hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

    Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  5. xcode的ios工程目录结构复习

    目录结构: a.supporting files: main.m和资源文件 xxx-info.plist:包含应用程序相关属性列表,如版本,程序名等 .pch文件:预编译头文件,相当于MFC里的std ...

  6. 使用Vue.js和Axios从第三方API获取数据 — SitePoint

    更多的往往不是,建立你的JavaScript应用程序时,你会想把数据从远程源或消耗一个[ API ](https:/ /恩.维基百科.org /维基/ application_programming_ ...

  7. SDUT2013级測试赛_D

    题目描写叙述 给出一棵含有n个点的树.每一个点权值为wi.求从根节点到叶子结点权值和最大的那条路经的权值和是多少. 输入 n(1<= n && n <= 10000). 接 ...

  8. 解析Java的JNI编程中的对象引用与内存泄漏问题

    JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native ...

  9. Unity 打包发布Android新手教学 (小白都能看懂的教学 ) [转]

    版权声明:本文为Aries原创文章,转载请标明出处.如有不足之处欢迎提出意见或建议,联系QQ531193915 扫码关注微信公众号,获取最新资源 最近在Unity的有些交流群里,发现好多Unity开发 ...

  10. hello-循环神经网络(RNN)原理

    主要的应用:机器翻译,自然语言处理,文本处理,语音识别, 图像描述生成 (Generating Image Descriptions), 图像问答QA.... 循环神经网络(RNN)原理通俗解释 1. ...