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. C#构造函数在继承时必须要求与父类型构造函数入参相同怎么办?

    摘要 我们都知道,C#中,在类型继承时,由于构造子类必须先构造其父类型的内容,因此,必须子类型的构造函数中调用父类型的构造函数(无参数的不需要显式声明). 但是往往我们会出现,子类型本身的构造函数大于 ...

  2. 获取Finacial dimension value的description 值

    public static Description findDimensionValueDescription(DimensionValue _dimensionValue, Name _dimens ...

  3. 线程,join合并线程

    在A中,调用B.join()那么,A会“等”B先执行 public class Join01 extends Thread { @Override public void run() { int su ...

  4. 【逐步完善】MySql索引相关

    在表中对某个字段添加索引: alter table tablename add index (columnname);

  5. OpenWrt自定义和官方一样的固件

    我用的OpenWrt版本是Barrier Breaker 14.07,硬件是NetGear WNDR4300. 我自定义固件的目的是把固件的根分区扩到最大(100MB,总FLASH是128MB),试过 ...

  6. Commons-Collections 集合工具类的使用

    package com.bjsxt.others.commons; import java.util.ArrayList; import java.util.List; import org.apac ...

  7. java 接口中模拟浏览器 请求webservice 接受返回数据

    使用HttpClient 所需jar:commons-codec-1.9.jar,commons-httpclient-3.1.jar try { HttpClient client = new Ht ...

  8. Spark Streaming中空RDD处理及流处理程序优雅的停止

    本期内容 : Spark Streaming中的空RDD处理 Spark Streaming程序的停止 由于Spark Streaming的每个BatchDuration都会不断的产生RDD,空RDD ...

  9. Docker学习过程中遇到的问题及解决方法

    1.重新安装Docker后,运行不起来 [root@zyt-test-14-53 ~]# docker infoCannot connect to the Docker daemon. Is the ...

  10. Window 对象详解 转自 http://blog.csdn.net/jcx5083761/article/details/41243697

    详解HTML中的window对象和document对象 标签: HTMLwindowdocument 2014-11-18 11:03 5884人阅读 评论(0) 收藏 举报 分类: HTML& ...