Spring之AOP(面向切面编程)_入门Demo
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态植入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。然而殊途同归,实现AOP的技术特性却是相同的,分别为:
1 join point(连接点):是程序执行中的一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个join point。
2 point cut(切入点):本质上是一个捕获连接点的结构。在AOP中,可以定义一个point cut,来捕获相关方法的调用。
3 advice(通知):是point cut的执行代码,是执行“方面”的具体逻辑。
4 aspect(方面):point cut和advice结合起来就是aspect,它类似OOP中定义的一个类,但它代表的更多是对象间横向的关系。
5 introduce(引入):为对象引入附加的方法或属性,从而达到修改对象结构的目的。有的AOP工具又将其称为mixin。
上述的技术特性组成了基本的AOP技术,大多数AOP工具均实现了这些技术。它们也可以是研究AOP技术的基本术语。
举例:假设有在一个应用系统中,有一个共享的数据必须并发同时访问,首先,将这个数据封装在数据对象中,同时,将有多个访问类,专门用于在同一时刻访问这同一个数据对象。
*Demo实验:
a.创建两个接口类:TestServiceInter,TestServiceInter2,代码如下:
// TestServiceInter
public interface TestServiceInter {
public void sayHello();
}
// TestServiceInter2
public interface TestServiceInter2 {
public void sayBye();
}
b.创建一个类Test1Service实现以上接口
public class Test1Service implements TestServiceInter,TestServiceInter2 {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void sayHello() {
System.out.println("hi"+name);
}
@Override
public void sayBye() {
System.out.println("bye"+name);
}
}
c.创建applicationContext.xml,配置必要的数据源和被代理的对象,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 配置被代理的对象 -->
<bean id="test1Service" class="com.ansibee.aop.Test1Service">
<property name="name" value="关羽"></property>
</bean>
</beans>
d.创建一个前置通知类MyMethodBeforeAdvice实现MethodBeforeAdvice接口,目的为了在执行sayHello()方法之前执行此段代码。代码如下:
public class MyMethodBeforeAdvice implements MethodBeforeAdvice{
/**
* method:被调用的方法名
* args:给method传递的参数
* target:目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println("*************");
System.out.println("日志记录:"+method.getName());
}
}
创建一个后置通知类MyAfterReturningAdvice实现AfterReturningAdvice接口,目的为了在执行sayBye()方法之后执行此段代码。代码如下:
public class MyAfterReturningAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println("关闭资源");
}
}
最后创建一个环绕通知类MyMethodInterceptor实现MethodInterceptor接口,环绕通知=前置通知+目标方法执行+后置通知,proceed ()方法就是用于启动目标方法执行的。代码如下:
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// TODO Auto-generated method stub
System.out.println("调用方法前执行");
Object obj = arg0.proceed();
System.out.println("调用方法后执行");
return obj;
}
}
e.完成上述操作后去applicationContext.xml文件中进行相应的配置。代码如下:
</bean>
<!-- 配置前置通知 -->
<bean id="MyMethodBeforeAdvice" class="com.ansibee.aop.MyMethodBeforeAdvice"></bean>
<!-- 定义前置通知的接入点 -->
<bean id="MyMethodBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="MyMethodBeforeAdvice"></property>
<property name="mappedNames">
<list>
<value>sayHello</value>
</list>
</property>
</bean>
<!-- 配置后置通知 -->
<bean id="MyAfterReturningAdvice" class="com.ansibee.aop.MyAfterReturningAdvice"></bean> <!-- 配置环绕通知 -->
<bean id="MyMethodInterceptor" class="com.ansibee.aop.MyMethodInterceptor"></bean>
<!-- 配置代理对象 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置代理的接口集 -->
<property name="proxyInterfaces">
<list>
<value>com.ansibee.aop.TestServiceInter</value>
<value>com.ansibee.aop.TestServiceInter2</value>
</list>
</property>
<!-- 把通知织入到代理对象 -->
<property name="interceptorNames">
<!-- 相当于把前置通知和代理对象关联,可以把通知看作拦截器-->
list>
<!-- 织入前置通知,后置通知,环绕通知-->
<value>MyMethodBeforeAdviceFilter</value>
<!-- 使用自定义切入点控制前置使用 -->
<value>MyAfterReturningAdvice</value>
<value>MyMethodInterceptor</value>
</list>
</property>
<!-- 通知被代理对象,可以指定-->
<property name="target" ref="test1Service"></property>
</bean>
f.完成一系列配置后,可以进行测试了,测试类代码如下:
public class TestMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("com/ansibee/aop/applicationContext.xml");
TestServiceInter ts = (TestServiceInter) ac.getBean("proxyFactoryBean");
ts.sayHello();
((TestServiceInter2)ts).sayBye();
}
}
然后run Java Application,运行结果如图
Spring之AOP(面向切面编程)_入门Demo的更多相关文章
- Spring:AOP面向切面编程
AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...
- Spring 08: AOP面向切面编程 + 手写AOP框架
核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...
- Spring框架 AOP面向切面编程(转)
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring的AOP面向切面编程
什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...
- spring:AOP面向切面编程02
参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...
- Spring注解 - AOP 面向切面编程
基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...
- Spring框架——AOP面向切面编程
简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...
- 【spring源码学习】spring的AOP面向切面编程的实现解析
一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口 => ...
- 详解Spring框架AOP(面向切面编程)
最近在学习AOP,之前一直很不明白,什么是AOP?为什么要使用AOP,它有什么作用?学完之后有一点小小的感触和自己的理解,所以在这里呢就跟大家一起分享一下 AOP(Aspect-Oriented Pr ...
随机推荐
- top、ps -ef、ps aux的区别及内容详解
1.top和ps的区别 ps是静态查看进程--------top是动态(持续监控)进程 ps只是查看进程-----------top还可以监视系统性能,如平均负载,cpu和内存的消耗 2.ps -ef ...
- 理解Java中的final关键字
final关键字的基本用法 1. 修饰类 出于安全考虑,类无法被继承 2. 修饰方法 防止继承类修改方法private方法会隐式指定为final方法: 3. 修饰变量 基本数据类型,初始化后不能再修改 ...
- Sqlmap爆库命令的简单使用
转载:https://blog.csdn.net/qq_41617034/article/details/89502428 测试地址:因为涉及商业隐私,这里就不列啦 我这里用的是windows,并没有 ...
- C# 9.0 新特性预览 - 顶级语句
C# 9.0 新特性预览 - 顶级语句 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们 ...
- 趣图:普通人讲故事 VS 程序员讲故事
扩展阅读 趣图:我说自己菜 vs 大佬说自己菜 趣图:客户需求VS客户预算 趣图:在外行人眼中的程序员 如何处理前任程序员留下的代码 一个故事讲清楚NIO
- zabbix_server.conf配置文件参数
NodeID: 在amster-child 的分布式架构中,这个ID是唯一标识zabbix node的号码 ListenPort:Trapper 类型Item监听的端口, SourceIP: 在连接其 ...
- burp suite 之 intruder(入侵者)
intruder:包括自动提交请求的功能 登录密码 撞库 注入 脱裤 Fuzz Burp intruder包含四个模块: Target:攻击的网站目标的详情信息 Positions :用来设置攻击类型 ...
- 微信小程序-实现文字跑马灯-wepy
百度蛮多例子的,但是代码太长懒得看了 前言 要实现跑马灯主要就是获得判断开始定界和结束定界, 1.9.3新增的wxml操作接口 就可以拿到节点长宽等属性,当然你也可以直接用 文字数量 * 文字大小(注 ...
- 怎么摆脱又臭又长的 Git 命令?
在使用 Git 的时候,虽然大部分时候我们用的是图形客户端,但图形客户端不能解决所有的操作,所以,也少不了要需要使用命令行的时候. 但有些 Git 命令和参数确实又不好记,甚至有的命令每次要用的时候需 ...
- 在程序开发中,++i 与 i++的区别在哪里?
哈哈哈! 从大学开始又忘了...蜜汁问题哈 参考来源:https://www.zhihu.com/question/19811087/answer/80210083 i++ 与 ++i 的主要区别有两 ...