AOP (Aspect-OrientedProgramming)面向切面编程
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接口代码
- public interface IUserServ {
- List<User> findAllUser();
- int deleteUserById(User user);
- int saveUser(User user);
- }
UserServImpl实现类代码
- public class UserServImpl implements IUserServ {
- public int deleteUserById(User user) {
- System.out.println("******执行删除方法******");
- return 0;
- }
- public List<User> findAllUser() {
- System.out.println("*******执行查询方法*******");
- return null;
}
- public int saveUser(User user) {
- System.out.println("*******执行添加方法********");
- return 0;
- }
- }
LogHandler类代码
- public class LogHandler implements InvocationHandler {
- //目标对象
- private Object targetObject;
- /**
- * 创建动态代理类
- * @return object(代理类)
- */
- public Object createProxy(Object targetObject){
- this.targetObject = targetObject;
- return Proxy.newProxyInstance(
- targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Object obj = null;
- try {
- beforeLog();
- //obj: 目标对象--->代理对象的返回值--->返回给调用者的信息
- //this.invoke("目标对象","代理对象给目标对象传递参数");
- //调用目标对象中方法
- obj = method.invoke(targetObject, args);
- afterLog();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return obj;
- }
//日志管理方法
- private void beforeLog(){
- System.out.println("开始执行");
- }
- private void afterLog(){
- System.out.println("执行完毕");
- }
}
ActionTest测试类代码:
- public class ActionTest {
- public static void main(String[] args) {
- //创建代理对象iuserServ
- LogHandler handler = new LogHandler();
- IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());
- iuserServ.deleteUserById(new User());
- }
- }
动态代理类:
(1)实现InvocationHandler接口
(2)创建代理类(通过java API)
Proxy.newProxyInstance(动态加载代理类,代理类实现接口,使用handler);
(3)调用invoke方法(虚拟机自动调用方法)
日志处理
//调用目标对象
method.invoke("目标对象","参数");
日志处理
通过代理对象--(请求信息)-->目标对象---(返回信息)----> 代理对象
Spring AOP使用(2.x版本之后)
IUserServ接口代码与UserServImpl实现类代码和上述代码相同
LogAdvice中
- public class LogAdvice {
- public void beforeLog(){
- System.out.println("开始执行");
- }
- public void afterLog(){
- System.out.println("执行完毕");
- }
- }
applicationContext.xml中
- <!-- spring2.x后 -->
- <!-- 目标对象 -->
- <bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>
- <!-- 通知 -->
- <bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>
- <aop:config>
- <aop:aspect id="logAspect" ref="logAdvice">
- <!-- 切入点 -->
- <aop:pointcut id="beforePointCut"
- expression="execution(* saveUser*(..))"/>
- <aop:pointcut id="afterPointCut"
- expression="execution(* saveUser*(..))"/>
- <!-- 织入(通知作用于切入点) -->
- <aop:before method="beforeLog" pointcut-ref="beforePointCut"/>
- <aop:after method="afterLog" pointcut-ref="afterPointCut"/>
- </aop:aspect>
- </aop:config>
测试类:
- public class ActionTest {
- public static void main(String[] args) {
- ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
- IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");
- iuserServ.deleteUserById(new User());
- iuserServ.findAllUser();
- iuserServ.saveUser(new User());
- }
- }
AOP (Aspect-OrientedProgramming)面向切面编程的更多相关文章
- 理解AOP思想(面向切面编程)
AOP:面向切面编程,相信很多刚接触这个词的同行都不是很明白什么,百度一下看到下面这几句话: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预 ...
- Spring AOP——Spring 中面向切面编程
前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识. 部分参考资料: <Spring实战(第4版)> <轻量级 JavaEE ...
- Javascript aop(面向切面编程)之around(环绕)
Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...
- 论AOP面向切面编程思想
原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...
- Spring核心AOP(面向切面编程)总结
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75208354冷血之心的博客) 1.AOP概念: 面向切面编程,指扩 ...
- 面向切面编程-AOP的介绍
AOP简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象 ...
- Spring中的面向切面编程(AOP)简介
一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...
- Spring AOP 面向切面编程入门
什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...
- (语法基础)浅谈面向切面编程(AOP)
一:前言 面向切面编程是一个很重要的编程思想,想要写出一个便于维护的程序,理解AOP并且能熟练的在实际编程中合理的运用AOP思想是很有必要的 二:AOP的基本概念 基础概念:AOP中文翻译面向切面编程 ...
- Spring-05 -AOP [面向切面编程] -Schema-based 实现aop的步骤
一.AOP [知识点详解] AOP:中文名称面向切面编程 英文名称:(Aspect Oriented Programming) 正常程序执行流程都是纵向执行流程 3.1 又叫面向切面编程,在原有纵向执 ...
随机推荐
- ASCIITable: 演示 Arduino 串口输出的进阶功能
原文地址 - https://www.arduino.cc/en/Tutorial/ASCIITable ASCII字符表 本例展示了高级的串口打印功能,通过本功能可以在Arduino软件(IDE)的 ...
- Python中__init__方法
注意1.__init__并不相当于C#中的构造函数,执行它的时候,实例已构造出来了. 1 2 3 4 5 class A(object): def __init__(self,name): ...
- pointer on c
http://blog.csdn.net/daniel_ice/article/details/6857019 http://www.cppblog.com/cuigang/archive/2008/ ...
- openlayers中实现自定冒泡的效果
自定义的Openlayers.Popup.FreshCloud继承自Openlayers.Popup.Framed,实现了比较简洁的冒泡效果,详细代码如下 /** * Class: OpenLayer ...
- oracle 邮件发送
CREATE OR REPLACE PROCEDURE PRC_sendmail(p_receiver VARCHAR2, -- 邮件接收人 ...
- (Hibernate进阶)Hibernate映射——一对一双向关联映射(六)
上一篇博客我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.如图所示: 关键原因在于对象模型具有方向性: 单向: ...
- IntelliJ IDEA常用设置及快捷键
IntelliJ IDEA是一款非常优秀的JAVA编辑器,初学都可会对其中的一些做法感到很别扭,刚开始用的时候我也感到很不习惯,在参考了网上一些文章后在这里把我的一些经验写出来,希望初学者能快速适应它 ...
- Xformode的坑
http://blog.csdn.net/u010335298/article/details/51983420
- For Your Dream
队名:Braveheart 队员介绍: 队长:李洋洋 队员:姚欢,杨仁波,张波,乔闯 项目名称:数据沈航 总体任务: 收集整理学校的数据,为每个想要了解沈航的人展现一份我们收集来的信息 项目分组: ( ...
- oracle contains
1. 查询住址在北京的学生SELECT student_id,student_nameFROM studentsWHERE CONTAINS( address, 'beijing' )remark: ...