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的更多相关文章

  1. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  2. Spring 08: AOP面向切面编程 + 手写AOP框架

    核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...

  3. Spring框架 AOP面向切面编程(转)

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  4. Spring的AOP面向切面编程

    什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...

  5. spring:AOP面向切面编程02

    参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...

  6. Spring注解 - AOP 面向切面编程

    基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...

  7. Spring框架——AOP面向切面编程

    简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...

  8. 【spring源码学习】spring的AOP面向切面编程的实现解析

    一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口  => ...

  9. 详解Spring框架AOP(面向切面编程)

    最近在学习AOP,之前一直很不明白,什么是AOP?为什么要使用AOP,它有什么作用?学完之后有一点小小的感触和自己的理解,所以在这里呢就跟大家一起分享一下 AOP(Aspect-Oriented Pr ...

随机推荐

  1. 高可用负载均衡集群——keepalive(1)

    Keepalived介绍 keepalived 是一个类似于 layer3, 4 & 5 交换机制的软件,也就是我们平时说的第 3 层.第 4 层和第 5层交换. Keepalived 的作用 ...

  2. 云计算openstack核心组件——horizon Web管理界面(10)

    一.horizon 介绍: 理解 horizon Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizone 所提供的 DashBoard 服务 ...

  3. 传值&传值引用

    转自http://www.cnblogs.com/androidsuperman/p/9012320.html 首先对传值和传引用要有个基本的概念 传值:传递的是值的副本.方法中对副本的修改,不会影响 ...

  4. 利用python简单实现unittest

    python3的eval方法 eval() 函数用来执行一个字符串表达式,并返回表达式的值 # 例如 a = [1,2,3,4] b = "a" print(eval(b)) # ...

  5. 执行引擎(Execution Engine)基础知识

    概述 执行引擎是Java虚拟机的核心组成部分之一 虚拟机是一个相对于"物理机"的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器.缓存.指令集和操作系统 ...

  6. 实现select下拉框的无限加载(懒加载)

    在实际开发中我们有时无法避免select下拉功能数据过大导致页面卡顿(如在我在一次迭代中有一个select项接口返回了5000多条数据).用户体验差!结合实际开发给出了3个解决方案: 方案1.sele ...

  7. 原生JavaScript封装的jsonp跨域请求

    原生JavaScript封装的jsonp跨域请求 <!DOCTYPE html> <html lang="en"> <head> <met ...

  8. 如何高雅的使用redis去获取一个值

    //场景,给定一个订单号来从缓存中查询一个订单信息; 步骤: 1从redis中直接获取,有数据就返回 2.如果redis中没有值,就查数据库 3.数据库查到的数据不为空,就刷到redis中 4.返回查 ...

  9. Spring学习(六)--Spring的IOC

    1.autowiring(自动依赖装配)的实现 自动装配中不需要对Bean属性做显示的依赖管理方式,只需要配置好autowiring的属性就可以,IOC容器会自动根据这个属性的配置通过反射自动找到属性 ...

  10. Apache HTTP Server 2.2.34安装

    Windows 下载 安装方式有自己编译源码和下载别人编译好的,这里选择从第三方下载,官网地址http://mirrors.tuna.tsinghua.edu.cn/apache//httpd/bin ...