1、jdk代理

针对接口进行代理,接口可以没有方法, InvocationHandler会拦截所有方法,不过好像意义不大....只能执行Object类的方法,执行结果有点奇怪...

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class TestJdkProxy { public static void main(String[] args) { //接口的实例对象,这里用的匿名对象
Test test = new Test() {
}; //拦截类
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数 System.out.println("代理前");
Object object = method.invoke(test, args);
System.out.println("代理后"); return object;
}
}; Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
test.getClass().getInterfaces(), invocationHandler); System.out.println("-------------------------------");
System.out.println(proxy.equals(proxy)); // ? 有点奇怪, 是false
System.out.println("-------------------------------");
System.out.println(Integer.toHexString(proxy.hashCode()));
System.out.println("-------------------------------");
System.out.println(proxy.toString()); // Object类的toString方法调用了一次hashCode方法, toString方法和hashCode方法只拦截了一次?
} public interface Test { } }

输出为:

-------------------------------
代理前
代理后
false
-------------------------------
代理前
代理后
61bbe9ba
-------------------------------
代理前
代理后
test.TestJdkProxy$1@61bbe9ba

接口有方法情况:

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class TestJdkProxy { public static void main(String[] args) { //接口的实例对象,这里用的匿名对象
Test test = new Test() {
@Override
public void test() {
System.out.println("执行代理的接口方法");
}
}; //拦截类
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数 System.out.println("代理前");
Object object = method.invoke(test, args);
System.out.println("代理后"); return object;
}
}; Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
test.getClass().getInterfaces(), invocationHandler);
proxy.test();
} public interface Test {
void test();
} }

输出为

代理前
执行代理的接口方法
代理后

2、cglib代理

代理类不能为final 类,

maven引入jar包

        <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
package test;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class TestCglibProxy { public static void main(String[] args) throws Exception { MethodInterceptor handler = new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//proxy为创建的代理类, 我的理解是对需要代理的类进行了继承(?), 所以需要代理的类不能为final类 System.out.println("代理前");
Object result = methodProxy.invokeSuper(proxy, objects);
System.out.println("代理后");
return result;
}
}; Enhancer enhancer = new Enhancer();
//设置需要代理的类,不能是final类
enhancer.setSuperclass(Test.class);
//设置方法拦截
enhancer.setCallback(handler);
//创建代理类,根据Test构造方法所需要的参数指定create参数, 如本例中Test类有String参数构造方法
Test test = (Test) enhancer.create(new Class[]{String.class}, new Object[]{"Aa"});
test.test();
System.out.println("-------------------------------");
test = (Test) enhancer.create();
test.test();
System.out.println("-------------------------------");
//对代理类的方法都会进行拦截, Object类的toString方法调用了一次hashCode方法, toString方法和hashCode方法都进行了拦截
System.out.println(test.toString());
System.out.println("-------------------------------");
System.out.println(test.equals(test));
} public static class Test { private String str; public void test() {
System.out.println("test : " + str);
} public Test() { } public Test(String string) {
str = string;
} } }

输出为

代理前
test : Aa
代理后
-------------------------------
代理前
test : null
代理后
-------------------------------
代理前
代理前
代理后
代理后
test.TestCglibProxy$Test$$EnhancerByCGLIB$$d7a97ec4@7506e922
-------------------------------
代理前
代理后
true

Java动态代理 ----- jdk代理与cglib代理的更多相关文章

  1. spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项

    大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述:   一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...

  2. 总结两种动态代理jdk代理和cglib代理

    动态代理 上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理. 这里再简单总结一下 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原 ...

  3. Java中jdk代理和cglib代理

    代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在Java中代理模式从实 ...

  4. 动态代理(二)—— CGLIB代理原理

    前篇文章动态代理(一)--JDK中的动态代理中详细介绍了JDK动态代理的Demo实现,api介绍,原理详解.这篇文章继续讨论Java中的动态代理,并提及了Java中动态代理的几种实现方式.这里继续介绍 ...

  5. jdk代理和cglib代理源代码之我见

    以前值是读过一遍jdk和cglib的代理,时间长了,都忘记入口在哪里了,值是记得其中的一些重点了,今天写一篇博客,当作是笔记.和以前一样,关键代码,我会用红色标记出来. 首先,先列出我的jdk代理对象 ...

  6. jdk代理和cglib代理

    1.jdk静态代理(静态代理和动态代理) 本质:在内存中构建出接口的实现类. 缺陷:只能对实现接口的类实现动态代理, 使用cglib可以对没有实现接口的类进行动态代理. 2.cglib动态代理     ...

  7. java 动态生成类再编译最后代理

    package spring.vhostall.com.proxy; public interface Store { public void sell(); } ------------------ ...

  8. Java代理模式精讲之静态代理,动态代理,CGLib代理

    代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...

  9. Spring框架_代理模式(静态代理,动态代理,cglib代理)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                 ...

随机推荐

  1. Gym - 101480K_K - Kernel Knights (DFS)

    题意:有两队骑士各n人,每位骑士会挑战对方队伍的某一个位骑士. (可能相同) 要求找以一个区间s: 集合S中的骑士不会互相挑战. 每个集合外的骑士必定会被集合S内的某个骑士挑战. 题解:讲真被题目绕懵 ...

  2. Alternating Direction Method of Multipliers -- ADMM

    前言: Alternating Direction Method of Multipliers(ADMM)算法并不是一个很新的算法,他只是整合许多不少经典优化思路,然后结合现代统计学习所遇到的问题,提 ...

  3. Python基础:12函数细节

    一:返回值 当没有显式地返回元素时,Python 会返回一个None.如果函数返回多个对象,python 把他们聚集起来并以一个元组返回. 二:创建函数 1:强烈推荐,在函数体之前,编写函数的文档字符 ...

  4. @atcoder - AGC034D@ Manhattan Max Matching

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 考虑一个二维平面,执行共 2*N 次操作: 前 N 次,第 i ...

  5. laravel博客后台操作步骤

  6. 【原生JS】图片预加载之有序预加载

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  7. 【原生JS】制作网页头部刷新进度条

    之前的某次番啬看到油管上有这么一个进度条,当时觉得挺好玩,一直想着做一个试试,刚才弄了一下写了一个不算太好看的简陋版本,哈哈. (本博客刷新会头部会出现,因为并没有真正的参与到浏览器加载是否完整这个渲 ...

  8. NLP进阶之(七)膨胀卷积神经网络

    NLP进阶之(七)膨胀卷积神经网络1. Dilated Convolutions 膨胀卷积神经网络1.2 动态理解1.2.2 转置卷积动画1.2.3 理解2. Dilated Convolutions ...

  9. 31页PPT:基于Spark的移动大数据挖掘

    31页PPT:基于Spark的移动大数据挖掘 数盟11.16 Data Science Meetup(DSM北京)分享:基于Spark的移动大数据挖掘分享嘉宾:张夏天(TalkingData首席数据科 ...

  10. [转]来自后端的逆袭 blazor简介 全栈的福音

    背景 什么是SPA 什么是MPA MPA (Multi-page Application) 多页面应用指的就是最传统的 HTML 网页设计,早期的网站都是这样的设计,所之称为「网页设计」.使用 MPA ...