代理是啥?就是代替你执行你持有的主要功能,并且能在你的基础之上完成一些其他的功能。代理的目的就是生成一个和原对象具有同样功能的对象。在Java中,代理是一种设计模式。在Spring的面向切面编程(AOP)中,主要就是利用动态代理来实现代码的织入。

代理分为动态代理和静态代理。顾名思义,动态代理比静态代理扩展性更高,动态代理不用为每一个实现类维护一个代理类。

静态代理

为不同的被代理类都维护一个代理类,维护工作量大,不利于扩展。

建立接口类,即被代理类。

Worker.java 工人接口类

public interface Worker {

	public void working();

	public void resting();
}

SimpleWorker.java 工人实现类

public class SimpleWorker implements Worker {

	@Override
public void working() {
System.out.println("I'm working!");
} @Override
public void resting() {
System.out.println("I'm resting!");
} }

需求,通过代理调用SimpleWorker的具体的方法,且处理其他逻辑(输出一句话):

public class WorkerProxy {

	private Worker worker;

        // 构造函数传入需要执行的类
public WorkerProxy(Worker worker) {
this.worker = worker;
} // 代理方法,调用具体实现方法
public void working() {
System.out.println("excute static proxy.");
worker.working();
}
}

运行结果:

excute static proxy.
I'm working!

动态代理

动态代理分为JDK动态代理与CGLIB动态代理。

JDK动态代理

JDK动态代理是jre库提供的一种方法,无需额外引入。它是通过类的接口生成代理类。

生成一个jdk代理,需要实现InvocationHandler接口,重写invoke方法。再用Proxy.newProxyInstance去生成代理类。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* jdk 动态代理
* @author guilin
*
*/
public class JdkProxy implements InvocationHandler{ private Object target; public JdkProxy(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("excute jdk proxy.");
Object result = method.invoke(target, args);
return result;
} public Object getInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}

测试类:

public class Test {
public static void main(String[] args) {
// JDK 动态代理
SimpleWorker simpleWorker = new SimpleWorker();
JdkProxy dynamicProxy = new JdkProxy(simpleWorker);
Object proxyObj = dynamicProxy.getInstance();
Worker obj = (Worker) proxyObj;
obj.working();
}
}

运行结果:

excute jdk proxy.
I'm working!

CGLIB动态代理

CGLIB是通过继承父类的公有方法,然后进行重写来实现的。在代码中代理类需要实现MethodInterceptor接口,重写intercept方法。配合Enhancer生成动态代理类。

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{ @Override
public Object intercept(Object obj, Method method, Object[] aobj, MethodProxy methodproxy) throws Throwable {
System.out.println("excute cglib proxy.");
// 执行父类方法
Object result = methodproxy.invokeSuper(obj, aobj);
return result;
} public Object getInstance(Class<?> superClass) {
// 获取代理实例
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(superClass);
enhancer.setCallback(this);
return enhancer.create();
} }

测试类:

public class Test {
public static void main(String[] args) {
// CGLIB 动态代理
CglibProxy cglibProxy = new CglibProxy();
Object instance = cglibProxy.getInstance(SimpleWorker.class);
Worker obj2 = (Worker) instance;
obj2.working();
}
}

运行结果:

excute cglib proxy.
I'm working!

Spring 默认使用jdk动态代理,而当类没有接口类时,使用CGLIB进行代理。

关于Java代理那些事儿的更多相关文章

  1. Java代理模式

    java代理模式及动态代理类 1.      代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...

  2. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  3. java代理的深入浅出(二)-CGLIB

    java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...

  4. java代理的深入浅出(一)-Proxy

    java代理的深入浅出(一)-Proxy 1.什么是代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事 ...

  5. Java代理(静态/动态 JDK,cglib)

    Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...

  6. JAVA代理机制

    JAVA代理相关主要知识如下: (1)利用代理可以在运行时创建一个实现了一组给定接口的新类.         这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用. (2)假设有一个表示接口的C ...

  7. ajax发送请求跨域 - uri java代理

    问题:ajax发送请求出现cors跨域 解决办法:可以通过java代理的方式,后台发送请求 1.get请求 public void proxyGet(String url) { try { URL r ...

  8. java代理通俗简单解析

    1         代理 1.1            代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...

  9. Java 代理模式

    熟悉设计模式的人对于代理模式可能都不陌生.那什么事代理呢,例如我们要买一件国外的商品,但是自己买不到只能去找代购,这个代购就是我们的代理.我们来了解下java中的代理 静态代理 我们来举一个开车的例子 ...

随机推荐

  1. TortoiseGit的使用(一)

    博客园换了新颜,立刻给我的感觉就是还不如原来的老古董界面呢.没办法呀,毕竟主要是习惯了.咱也不吐槽了,慢慢地,习惯就好,博客园也在逐步改善. 目录 Git和TortoiseGit下载安装 稍微笼统地介 ...

  2. 关于setTimeout的用法注意事项

    setTimeout setTimeout的定义:setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. setTimeout的用法:setTimeout(代码片段,执行代码等待的毫 ...

  3. NLTK库WordNet的使用方法实例

    1.在代码中引入wordnet包 >>>from nltk.corpus import wordnet as wn 2.查询一个词所在的所有词集(synsets) >>& ...

  4. python爬虫之Beautiful Soup基础知识+实例

    python爬虫之Beautiful Soup基础知识 Beautiful Soup是一个可以从HTML或XML文件中提取数据的python库.它能通过你喜欢的转换器实现惯用的文档导航,查找,修改文档 ...

  5. mycat数据库集群系列之数据库多实例安装

    mycat数据库集群系列之数据库多实例安装 最近在梳理数据库集群的相关操作,现在花点时间整理一下关于mysql数据库集群的操作总结,恰好你又在看这一块,供一份参考.本次系列终结大概包括以下内容:多数据 ...

  6. Java的注解浅析

    人的一生就像一篇文章,只有经过多次精心修改,才能不断完善 Java注解概念理解: Java注解又称为Java标注,是JDK5引入的一中注释机制,Java中大家熟悉的五种注解分别是:@Override, ...

  7. vue cli3.0使用svg全过程

    VUE-cli3使用 svg-sprite-loader svg-sprite-loader 的插件,用来根据导入的 svg 文件自动生成 symbol 标签并插入 html 1.安装依赖 npm i ...

  8. 安装Ubuntu 出现ubi partman crashed,ubi-partman failed with exit code 10

    出现这个问题好像是因为硬盘中有遗留的raid信息导致. 在安装选项中添加 nodmraid参数,再启动进行安装就好了 如果不会添加参数可以参考这篇文章:安装ubuntu时黑屏三种解决办法 就和添加 n ...

  9. C++指针变量的基本写法

    指针变量与应用——动态数组 在C++中,有一种神奇的变量,它不可以表示一个值,但是可以表示某个元素的地址,通过地址来访问这个元素. 打个比方:你有一张地图和一个坐标,你就可以通过访问这个坐标来达到你访 ...

  10. CF 1329B Dreamoon Likes Sequences

    传送门 题目: Dreamoon likes sequences very much. So he created a problem about the sequence that you can' ...