AOP

OOP 面向对象编程 适合自上向下,却不适合自左向右

AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。

横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。

Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。

一般应用:日志记录、事物控制、权限控制

一、基础定义

  • 切面(Aspect): 就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。宏观上要关注的编程方面,比如安全管理方面,日志记录方面,而这些都只是宏观上的,没有任何代码实现,就好像这样说:我这个系统要一个安全管理系统等等,就是大至上需要这个切面功能。
  • 通知(Advice):是切面的具体实现。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际应用中通常是切面类中的一个方法,具体属于哪类通知,同样是在配置中指定的。
  • 连接点(Joinpoint):就是程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出或字段修改等,但Spring只支持方法级的连接点。
  • 切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。
  • 目标对象(Target):就是那些即将切入切面的对象,也就是那些被通知的对象。这些对象中已经只剩下干干净净的核心业务逻辑代码了,所有的共有功能代码等待AOP容器的切入。
  • 代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。
  • 织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译期、类装载期及运行期,当然不同的发生点有着不同的前提条件。譬如发生在编译期的话,就要求有一个支持这种AOP实现的特殊编译器;发生在类装载期,就要求有一个支持AOP实现的特殊类装载器;只有发生在运行期,则可直接通过Java语言的反射机制与动态代理机制来动态实现。

动态代理:

IUserServ接口代码

  1. public interface IUserServ {
  2. List<User> findAllUser();
  3. int deleteUserById(User user);
  4. int saveUser(User user);
  5. }

UserServImpl实现类代码

  1. public class UserServImpl implements IUserServ {
  2. public int deleteUserById(User user) {
  3. System.out.println("******执行删除方法******");
  4. return 0;
  5. }
  6. public List<User> findAllUser() {
  7. System.out.println("*******执行查询方法*******");
  8. return null;

}

  1. public int saveUser(User user) {
  2. System.out.println("*******执行添加方法********");
  3. return 0;
  4. }
  5. }

LogHandler类代码

  1. public class LogHandler implements InvocationHandler {
  2. //目标对象
  3. private Object targetObject;
  4. /**
  5. * 创建动态代理类
  6. * @return object(代理类)
  7. */
  8. public Object createProxy(Object targetObject){
  9. this.targetObject = targetObject;
  10. return Proxy.newProxyInstance(
  11. targetObject.getClass().getClassLoader(),
  12. targetObject.getClass().getInterfaces(), this);
  13. }
  14. @Override
  15. public Object invoke(Object proxy, Method method, Object[] args)
  16. throws Throwable {
  17. Object obj = null;
  18. try {
  19. beforeLog();
  20. //obj: 目标对象--->代理对象的返回值--->返回给调用者的信息
  21. //this.invoke("目标对象","代理对象给目标对象传递参数");
  22. //调用目标对象中方法
  23. obj = method.invoke(targetObject, args);
  24. afterLog();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. return obj;
  29. }

//日志管理方法

  1. private void beforeLog(){
  2. System.out.println("开始执行");
  3. }
  1. private void afterLog(){
  2. System.out.println("执行完毕");
  3. }

}

ActionTest测试类代码:

  1. public class ActionTest {
  2. public static void main(String[] args) {
  3. //创建代理对象iuserServ
  4. LogHandler handler = new LogHandler();
  5. IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());
  6. iuserServ.deleteUserById(new User());
  7. }
  8. }

动态代理类:

(1)实现InvocationHandler接口

(2)创建代理类(通过java API)

Proxy.newProxyInstance(动态加载代理类,代理类实现接口,使用handler);

(3)调用invoke方法(虚拟机自动调用方法)

日志处理
 //调用目标对象
 method.invoke("目标对象","参数");
 日志处理

通过代理对象--(请求信息)-->目标对象---(返回信息)----> 代理对象

Spring AOP使用(2.x版本之后)

IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogAdvice中

  1. public class LogAdvice {
  2. public void beforeLog(){
  3. System.out.println("开始执行");
  4. }
  5. public void afterLog(){
  6. System.out.println("执行完毕");
  7. }
  8. }

applicationContext.xml中

  1. <!-- spring2.x后 -->
  2. <!-- 目标对象 -->
  3. <bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>
  4. <!-- 通知 -->
  5. <bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>
  6. <aop:config>
  7. <aop:aspect id="logAspect" ref="logAdvice">
  8. <!-- 切入点 -->
  9. <aop:pointcut id="beforePointCut"
  10. expression="execution(* saveUser*(..))"/>
  11. <aop:pointcut id="afterPointCut"
  12. expression="execution(* saveUser*(..))"/>
  13. <!-- 织入(通知作用于切入点) -->
  14. <aop:before method="beforeLog" pointcut-ref="beforePointCut"/>
  15. <aop:after method="afterLog" pointcut-ref="afterPointCut"/>
  16. </aop:aspect>
  17. </aop:config>

测试类:

    1. public class ActionTest {
    2. public static void main(String[] args) {
    3. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    4. IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");
    5. iuserServ.deleteUserById(new User());
    6. iuserServ.findAllUser();
    7. iuserServ.saveUser(new User());
    8. }
    9. }

AOP (Aspect-OrientedProgramming)面向切面编程的更多相关文章

  1. 理解AOP思想(面向切面编程)

    AOP:面向切面编程,相信很多刚接触这个词的同行都不是很明白什么,百度一下看到下面这几句话: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预 ...

  2. Spring AOP——Spring 中面向切面编程

    前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识. 部分参考资料: <Spring实战(第4版)> <轻量级 JavaEE ...

  3. Javascript aop(面向切面编程)之around(环绕)

    Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...

  4. 论AOP面向切面编程思想

    原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...

  5. Spring核心AOP(面向切面编程)总结

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75208354冷血之心的博客) 1.AOP概念: 面向切面编程,指扩 ...

  6. 面向切面编程-AOP的介绍

    AOP简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象 ...

  7. Spring中的面向切面编程(AOP)简介

    一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...

  8. Spring AOP 面向切面编程入门

    什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...

  9. (语法基础)浅谈面向切面编程(AOP)

    一:前言 面向切面编程是一个很重要的编程思想,想要写出一个便于维护的程序,理解AOP并且能熟练的在实际编程中合理的运用AOP思想是很有必要的 二:AOP的基本概念 基础概念:AOP中文翻译面向切面编程 ...

  10. Spring-05 -AOP [面向切面编程] -Schema-based 实现aop的步骤

    一.AOP [知识点详解] AOP:中文名称面向切面编程 英文名称:(Aspect Oriented Programming) 正常程序执行流程都是纵向执行流程 3.1 又叫面向切面编程,在原有纵向执 ...

随机推荐

  1. Python 之 threading

    创建多线程常用的三种方法: 创建Thread的实例,传给它一个函数 创建Thread的实例,传给它一个可调用的类实例(不推荐) 派生Thread的子类,并创建子类的实例(推荐) 创建Thread的实例 ...

  2. ACdream 1017 [分层图][网络流]

    /* 大连热身C题 不要低头,不要放弃,不要气馁,不要慌张 题意: 给一个城市路线图,给定起点给定终点.有n个货物从起点运送到终点.城市的边是无向边. 每个货物每天如果通过某条路,那么这天这条路只能运 ...

  3. php源码之遍历目录下的所有的文件

    <?php //遍历目录下的所有的文件 -- 递归调用 // http://www.manongjc.com/article/1495.html function get_all_file1($ ...

  4. C++设计模式-Command命令模式

    Command命令模式作用:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式 ...

  5. Geodatabase数据模型

    1  Geodatabase概念 Geodatabase是ArcInfo8引入的一种全新的面向对象的空间数据模型,是建立在DBMS之上的统一的.智能的空间数据模型.“统一”是指,Geodatabase ...

  6. Access、Hybrid和Trunk

    以太网端口有三种链路类型:Access.Hybrid和Trunk.Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口:Trunk类型的端口可以属于多个VLAN,可以接收和发送多个VL ...

  7. arcgis基于地形数据的坡度分析

    高程.坡度和坡向是小班中非常重要的因子,坡度对水土保持规划设计具有决定性的作用,是土地利用规划和治理措施配置首先要考虑的因素.如何利用地形数据对坡度进行分析呢,本文即将揭晓. 软件准备: locasp ...

  8. <读书笔记>软件调试之道 :从大局看调试-发现代码存在问题

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  9. css3 text-overflow属性

    页面: <ul> <li>· 测试测试测试测试测试测试</li> <li>· 测试测试测试测试测试测试</li> <li>· 测 ...

  10. opencv嫁接vlfeat densesift

    #include <opencv2/opencv.hpp> #include <iostream> extern "C" { #include <vl ...