Java使用动态代理实现AOP

参考资料:

http://www.importnew.com/15420.html
http://www.cnblogs.com/techyc/p/3455950.html

Spring是借助了动态代理(JDK dynamic proxy)和CGlib两种技术实现AOP的,本文将学习前人的例子使用动态代理模拟AOP的特性。

1. 环境

Java: jdk1.8.0_144

2. 学习动态代理Proxy.newProxyInstance()方法

它的三个参数如下

参数名 类型 说明
loader ClassLoader 被代理类的类加载器
interfaces Class<?>[] 被代理类实现的interface集合
h InvocationHandler 被代理类的所有方法调用,都会绑定到java.lang.reflect.InvocationHandler接口的invoke方法执行

3. 实现思路

  • 通过JDK dynamic proxy代理目标对象
  • 覆盖InvocationHandler的invoke方法,包装被代理对象的方法调用,动态添加逻辑来实现类似于after/before/around的AOP功能

在一定程度上,实现的思路与装饰器模式相似,它们区别在于

  • 装饰器模式中的包装类需要知道被包装类的接口细节,而这里不需要
  • 装饰器模式不需要使用反射和代理,而这里需要

4. 代码解析

https://github.com/hivsuper/study/tree/master/study-aop

  • 将被代理的类及其接口
public interface Calculator {
    public int add(int a, int b);
}
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}
  • 绑定被代理对象的调度接口
import java.lang.reflect.InvocationHandler;

public abstract class AbstractHandler implements InvocationHandler {
    private Object targetObject;

    public Object getTargetObject() {
        return targetObject;
    }

    public void setTargetObject(Object targetObject) {
        this.targetObject = targetObject;
    }
}
  • 生成代理的简单工厂
import java.lang.reflect.Proxy;
import java.util.List;

public class ProxyFactory {
    public static Object getProxy(Object targetObject, List<AbstractHandler> handlers) {
        Object proxyObject = null;
        if (handlers.size() > 0) {
            proxyObject = targetObject;
            for (AbstractHandler abstractHandler : handlers) {
                abstractHandler.setTargetObject(proxyObject);
                proxyObject = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                        targetObject.getClass().getInterfaces(), abstractHandler);
            }
            return proxyObject;
        } else {
            return targetObject;
        }
    }
}
  • 测试类
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.lxp.study.aop.AbstractHandler;
import org.lxp.study.aop.ProxyFactory;

public class CalculatorImplTest {

    @Test
    public void testAdd() throws Exception {
        Calculator calculator = new CalculatorImpl();
        AbstractHandler before = new AbstractHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("...before...");
                return method.invoke(getTargetObject(), args);
            }
        };
        AbstractHandler after = new AbstractHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = method.invoke(getTargetObject(), args);
                System.out.println("...after...");
                return result;
            }
        };
        AbstractHandler around = new AbstractHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                StringBuilder sb = new StringBuilder();
                for (Object arg : args) {
                    sb.append(arg).append(",");
                }
                System.out.println("Parameters:" + sb.substring(0, sb.length() - 1));
                Object result = method.invoke(getTargetObject(), args);
                System.out.println("Result:" + result);
                return result;
            }
        };
        List<AbstractHandler> handlers = new ArrayList<AbstractHandler>();
        handlers.add(before);
        handlers.add(after);
        handlers.add(around);
        Calculator proxy = (Calculator) ProxyFactory.getProxy(calculator, handlers);
        Assert.assertEquals(30, proxy.add(20, 10));
    }

}
时间: 2024-10-13 08:35:35

Java使用动态代理实现AOP的相关文章

【转载】Java JDK 动态代理(AOP)使用及实现原理分析

转自:http://blog.csdn.net/jiankunking/article/details/52143504 版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持

JAVA 反射 动态代理与AOP

摘自 b站尚硅谷JAVA视频教程 原文地址:https://www.cnblogs.com/superxuezhazha/p/12358469.html

Java动态代理--&gt;Spring AOP

引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www.iteye.com/topic/1123293 [3] 属性

java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于 Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是 java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Cla

java的动态代理

最近在研究这个java的ssh三大框架,当看到这个spring的aop(aspect-orinted-programming)的时候,其中提到了这个java的动态代理机制,这个动态代理,我以前似乎看过,但是那是设计模式的事情.所以有一次搜索到这个动态代理,对这个动态代理进行一个研究,记录自己的进步. spring的aop编程是一个面向切面的编程思想,和这个面向对象的编程是一个补充的关系,不是一个对立的关系.面向对象强调和使用的从上到下的层次关系,但是aop编程使用的是从左到右的关系.一个是纵的关

java中动态代理实现机制

JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterface{ int sub(int a, int b); } 实现类 class Arithmetic implements AddInterface, SubInterface{ @Override public int sub(int a, int b) { return a-b; } @Override public i

(转)java的动态代理机制详解

原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有

[转载] java的动态代理机制详解

转载自http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理

java --- 设计模式 --- 动态代理

Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理使代码的重复更少,更便与维护 本文参考了满一行老师和马士兵老师的视频,在此表示Thanks. 假设小张通过QQ和一个网名为如花的妹纸聊天, 而在QQ的另一端,这个网名为如花的妹纸的name是小丽 但是,正在聊天的时候小丽生病了不想打字,小丽就找她的男朋友帮忙回应 小丽的男朋友在如花的QQ账号上与小张