AOP的概述(7)

什么是AOP?

  • AOP Aspect Oriented Programing 面向切面编程
  • AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
  • Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
  • AspecJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

AOP底层原理

就是代理机制:

  • 动态代理:(JDK中使用)

    • JDK的动态代理,对实现了接口的类生成代理.

Spring的AOP代理

  • JDK动态代理:对实现了接口的类生成代理
  • CGLib代理机制:对类生成代理

AOP的术语

  • Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.
  • Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
  • Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
  • Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
  • Target(目标对象):代理的目标对象
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.
  • spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
  • Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
  • Aspect(切面): 是切入点和通知(引介)的结合
解释以上名词:
  • joinpoit:连接点,指的是那些方法【可以】被拦截
  • pointcut:切入点,对哪些joinpoint进行拦截
  • advice:通知,指的是 【要 】增强的代码,(方法级别的增强)
  • introduction:引介,指的是一种特殊方式的advice(类级别的增强,在原有类上添加一个属性或者方法)
  • target:目标对象,呗增强的对象。
  • weaving(织入):是指增强(advice)应用到目标对象(targe)来创建新的代理对象的过程。
  • proxy:代理对象
  • Aspect(切面):是切入点和通知(引介)的结合(允许有多个切点和多个通知的结合)


以下是底层实现demo演示

AOP的底层实现

  • JDK动态代理(对实现接口的类进行代理):

接口类:

package cn.spring3.demo1;
/**
 * @author NOP
 * DAO接口
 */
public interface UserDao {
    public void add();
    public void update();
}

实现类:

package cn.spring3.demo1;
public class UserDaoImpl implements UserDao {
    public void add() {
        // TODO Auto-generated method stub
        System.out.println("添加用户");
    }
    public void update() {
        // TODO Auto-generated method stub
        System.out.println("修改用户");
    }
}

传统方式调用:

package cn.spring3.demo1;
import org.junit.Test;
public class SpringTest1 {
    @Test
    public void demo1() {
        UserDao userDao = new UserDaoImpl();
        userDao.add();
        userDao.update();
    }
}

如果增强add方法,怎么做呢?
方法一:

package cn.spring3.demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * @author NOP JDK动态类里的机制
 * 直接实现Handler,所以JDKProxy自身就是Handler
 */
public class JDKProxy implements InvocationHandler {
    private UserDao userDao;
    public JDKProxy(UserDao userDao) {
        super();
        this.userDao = userDao;
    }
    public UserDao createProxy() {
        /**
         * invocationHandler两种方式,一种匿名内部类的方式见JDKProxy1.java
         */
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass()
                .getClassLoader(), userDao.getClass().getInterfaces(), this);
        return proxy;
    }
    //调用目标对象的任何一个方法都相当于调用invoke();
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        if("add".equals(method.getName())){
            System.out.println("===日志记录===");
            Object result = method.invoke(userDao, args);
            return result;
        }
        return method.invoke(userDao, args);
    }
}

方法二:

package cn.spring3.demo1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author NOP JDK动态类里的机制
 */
public class JDKProxy1 {
    private UserDao userDao;

    public JDKProxy1(UserDao userDao) {
        super();
        this.userDao = userDao;
    }

    public UserDao createProxy() {
        /**
         * invocationHandler两种方式
         */
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass()
                .getClassLoader(), userDao.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        // TODO Auto-generated method stub
                        if (method.getName().equals("add")) {
                            System.out.println("===匿名内部类方式记录logs日志====");
                            Object result = method.invoke(userDao, args);
                            return result;
                        }
                        return method.invoke(userDao, args);
                    }
                });
        return proxy;
    }
}

编写测试类
对应JDKProxy.java

@Test
    public void demo2() {
        //被代理对象
        UserDao userDao = new UserDaoImpl();
        //创建代理对象的时候传入被代理对象
        UserDao proxy = new JDKProxy(userDao).createProxy();
        proxy.add();
        proxy.update();
    }
    测试结果:
===日志记录===
添加用户
修改用户

对应JDKProxy1.java

@Test
    public void demo3() {
        UserDao userDao = new UserDaoImpl();
        UserDao proxy = new JDKProxy1(userDao).createProxy();
        proxy.add();
        proxy.update();
    }
    测试结果:
===匿名内部类方式记录logs日志====
添加用户
修改用户

原文地址:http://blog.51cto.com/4534309/2112067

时间: 2024-10-22 07:56:54

AOP的概述(7)的相关文章

[Spring实战系列](16)面向切面编程(AOP)概述

1. 简介 在软件中,有些行为对于大多数应用都是通用的.日志,安全和事务管理的确很重要,但他们是都是应用对象主动参与的行为呢?如果让应用对象只关注自己所针对的业务领域问题,而其他方面的问题由其他应用对象来处理,这样会不会更好? 在软件开发中,分布于应用中多处的功能被称为横切关注点.通常,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑中).将这些横切关注点与业务逻辑相分离是面向切面编程索要解决的. 上图展示了一个被划分为模块的典型应用.每个模块的核心功能都是为特

aop的概述

支付部分,定义IPayService接口并定义支付方法“pay”,并定义了两个实现:“PointPayService”表示积分支付,“RMBPayService”表示人民币支付:并且在每个支付实现中支付逻辑和记录日志 记录日志时,如果使用oop,则每个接口的实现类里重复编写日志的代码,aop就是为了解耦,将日志的功能变成切面,在合适的时候织入到里面 在进行OOP开发时,都是基于对组件(比如类)进行开发,然后对组件进行组合,OOP最大问题就是无法解耦组件进行开发,比如我们上边举例,而AOP就是为了

九 AOP的概述

AOP : 面向切面编程,解决OOP(面向对象编程)开发遇到的问题,是oop的延伸和扩展 AOP的优点:不修改源码的情况下,对程序进行校验,日志记录,性能控制,事务控 SpringAOP底层的实现原理: JDK动态代理:只能对实现了接口的类产生代理.(实现接口默认JDK动态代理,底层自动切换) cglib动态代理(类似Javassist第三方的代理技术):对没有实现接口的类产生代理对象.生成子类对象. AOP采用了横向抽取机制取代了传统的纵向继承 原文地址:https://www.cnblogs

Spring AOP源码分析

AOP基本概述 Advice(通知) BeforeAdvice package org.springframework.aop; import java.lang.reflect.Method; public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, Object target) throws Throwable; } before是回调方法,在Adv

AOP技术分析

AOP的概述(http://www.cnblogs.com/lxp503238/p/6837653.html)        1. 什么是AOP的技术?        * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程        * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构        * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范      

轻量级的.NET对象查找服务和AOP开发框架Netop.Core源码解说(1)-导言

Netop.Core是我程序开发积累的一个轻量级的.NET对象查找服务和AOP开发框架,现将源码公开,共享给各位NET程序员后面相关的文章对这个开发框架进行程序解说和使用解说. Netop.Core--轻量级的.NET对象查找服务和AOP开发框架概述:1.    对象查找服务(本地服务实例生成,远程服务,WCF服务)和AOP服务.2.    其它普通服务:配置, 对话上下文,日志,缓冲等.3.    类库:Netop.Core.dll  4.    必需的外部类库:Microsoft.Pract

Spring框架 AOP(三)

AOP理论概述 Aspect Oriented Programming 面向切面编程 业界 AOP 实际上 OOP (面向对象编程 ) 延伸 -- OOP编程语言. AOP设计思想 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) 横向抽取代码复用,基于代理技术,在不修改原有对象代码情况下,对原有对象方法功能进行增强! ---- AOP 思想 Spring框架如何实现AOP Spring1.2 版本开始 开始支持AOP技术 (传统Spring AOP

Spring框架 教程

Spring教程 Spring教程...1 Spring框架概述...3 Spring是什么?...3 Spring的历史...4 Spring的使命(MissionStatement)...4 Spring受到的批判...4 Spring包含的模块...5 总结...6 Spring的IoC容器...6 用户注册的例子...7 面向接口编程...8 (用户持久化类)重构第一步--面向接口编程... 重构第二步--工厂(Factory)模式... 重构第三步--工厂(Factory)模式的改进.

Spring框架第二天

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption