热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring(三)__aop编程

aop(aspectorientedprogramming)面向切面编程,是对所有对象或者是一类对象编程几个重要的概念:1.切面(aspect):要实现的交叉功能&#

aop( aspect oriented programming )

 

面向切面编程,对所有对象或者是一类对象编程

 

几个重要的概念:

1.切面(aspect):要实现的交叉功能,是系统模块化的一个切面或领域。如日志记录。

2.连接点:应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出,或者要修改的 字段。

3.通知:切面的实际实现,他通知系统新的行为。如在日志通知包含了实 现日志功能的代码,如向日志文件写日志。通知在连接点插入到应用系统中。

4.切入点:定义了通知应该应用在哪些连接点,通知可以应用到AOP框架支持的任何连接点。

5.引入:为类添加新方法和属性。

6.目标对象:被通知的对象。既可以是你编写的类也可以是第三方类。

7.代理:将通知应用到目标对象后创建的对象,应用系统的其他部分不用为了支持代理对象而 改变。

8.织入:将切面应用到目标对象从而创建一个新代理对象的过程。织入是一个过程。织入发生在目标 对象生命周期的多个点上:

编译期:切面在目标对象编译时织入.这需要一个特殊的编译器.

类装载期:切面在目标对象被载入JVM时织入.这需要一个特殊的类载入器.

运行期:切面在应用系统运行时织入.

 

创建切面的方式:

还有一种引用通知方式。总共五种类型,下面一一举例实现:

编程说明:

步骤:

1.定义接口

2.编写对象(被代理对象=目标对象)

3.编写通知(前置通知目标方法调用前调用)

4.在beans.xml文件配置

4.1 配置 被代理对象=目标对象

4.2 配置通知

4.3 配置代理对象 ProxyFactoryBean的对象实例

4.3.1 代理接口集

4.3.2 织入通知

4.3.3 配置被代理对象

 

一.定义接口:

接口1:

public interface TestServiceInter {public void sayHello();
}

接口2:

public interface TestServiceInter2 {public void sayBye();
}

 

二、编写对象

public class Test1Service implements TestServiceInter,TestServiceInter2 {private String name; public String getName() {return name;}public void setName(String name) {this.name = name;}public void sayHello() {System.out.println("hi "+name);}public void sayBye() {System.out.println("bye "+name);//int i=9/0;
}
}

 

三、编写通知

1.前置通知

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {/*** method: 被调用方法名字* args: 给method传递的参数* target: 目标对象*/public void before(Method method, Object[] args, Object target)throws Throwable {System.out.println("..............");System.out.println("记录日志..."+method.getName());}
}

该接口提供了获得目标方法、参数和目标对象的机会。不能够改变运行时参数,即不能替换参数对象和目标对象。

注意在方法结束后不返回任何值。原因是该接口返回后,目标方法将会被调用,应该返回目标对象的返回值。

该接口唯一能 阻止目标方法被调用的途径是抛出异常或(System.exit())。

 

2.后置通知

与前置通知类似

public class MyAfterReturningAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object returnValue, Method method,Object[] args, Object target) throws Throwable System.out.println("关闭资源。。。。");}
}

 

3.环绕通知

public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation arg0) throws Throwable {System.out.println("调用方法前。。。");Object obj=arg0.proceed(); //目标对象方法的调用执行System.out.println("调用方法后。。。");return obj;}
}

该接口同前两种通知有两个重要区别:

1.该通知能够控制目标方法 是否真的被调用。通过invocation.proceed()方法来调用。

2.该通知可以控制返回的对象。可以返回一个与proceed()方法返回对象完全不同的对象。但要谨慎使用。

 

4.异常通知

public class MyThrowsAdvice implements ThrowsAdvice {public void afterThrowing(Method m,Object[] os,Object target,Exception throwable){System.out.println("出大事了"+throwable.getMessage());}}

public interface ThrowsAdvice{

}

该接口为标识性接口,没有任何方法,但实现该接口的类必须要有如下形式的方法:

public void afterThrowing(Throwable throwable);

public void afterThrowing(Method m,Object[] os,Object target,Exception throwable);

第一个方法只接受一个参数:需要抛出的异常。 第二个方法接受异常、被调用的方法、参数以及目标对象。

 

 5.引入通知

如果不能表达在应用系统的什么地方应用 通知的话,通知将毫无用处,这就是切入点的用处。

切入点决定了一个特定的类的特定方法是否满足一定的规则。若符合,通知就应用到该方法上。

引入通知只需要在beans.xml中自定义切入点来控制通知。

 

四、beans.xml配置

beans.xml


xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" >
class="com.hsp.aop.Test1Service">


class="com.hsp.aop.MyMethodBeforeAdvice" />

class="com.hsp.aop.MyAfterReturningAdvice"/>

class="com.hsp.aop.MyMethodInterceptor" />

class="com.hsp.aop.MyThrowsAdvice"/>

class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >sayHello

class="org.springframework.aop.framework.ProxyFactoryBean">

com.hsp.aop.TestServiceIntercom.hsp.aop.TestServiceInter2

myMethodBeforeAdviceFiltermyAfterReturningAdvicemyMethodInterceptormyThrowsAdvice


测试:

public static void main(String[] args) { ApplicationContext ac=new ClassPathXmlApplicationContext("com/hsp/aop/beans.xml");TestServiceInter ts=(TestServiceInter) ac.getBean("proxyFactoryBean"); ts.sayHello();((TestServiceInter2)ts).sayBye(); }

执行结果:

现在加入打印代理对象的类型的语句:

public static void main(String[] args) { ApplicationContext ac=new ClassPathXmlApplicationContext("com/hsp/aop/beans.xml");TestServiceInter ts=(TestServiceInter) ac.getBean("proxyFactoryBean"); System.out.println("ts的类型是"+ts);ts.sayHello();((TestServiceInter2)ts).sayBye(); }

执行结果:

ts是个代理对象,从中还可以看出只要代理对象被调用就会执行织入通知。

提问? springaop中,当你通过代理对象去实现aop的时候,获取的ProxyFactoryBean是什么类型?

: 返回的是一个代理对象,如果目标对象实现了接口,则spring使用jdk 动态代理技术,如果目标对象没有实现接口,则spring使用CGLIB技术.

 

 

转:https://www.cnblogs.com/xiangkejin/p/6065181.html



推荐阅读
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
author-avatar
多米音乐_34249295
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有