关于Java代理那些事儿
代理是啥?就是代替你执行你持有的主要功能,并且能在你的基础之上完成一些其他的功能。代理的目的就是生成一个和原对象具有同样功能的对象。在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代理那些事儿的更多相关文章
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
- java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...
- java代理的深入浅出(二)-CGLIB
java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...
- java代理的深入浅出(一)-Proxy
java代理的深入浅出(一)-Proxy 1.什么是代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事 ...
- Java代理(静态/动态 JDK,cglib)
Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
- JAVA代理机制
JAVA代理相关主要知识如下: (1)利用代理可以在运行时创建一个实现了一组给定接口的新类. 这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用. (2)假设有一个表示接口的C ...
- ajax发送请求跨域 - uri java代理
问题:ajax发送请求出现cors跨域 解决办法:可以通过java代理的方式,后台发送请求 1.get请求 public void proxyGet(String url) { try { URL r ...
- java代理通俗简单解析
1 代理 1.1 代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...
- Java 代理模式
熟悉设计模式的人对于代理模式可能都不陌生.那什么事代理呢,例如我们要买一件国外的商品,但是自己买不到只能去找代购,这个代购就是我们的代理.我们来了解下java中的代理 静态代理 我们来举一个开车的例子 ...
随机推荐
- 2020-06-15:Redis分布式锁怎么解锁?
福哥答案2020-06-15: 答案来自群成员:1.setnx:del2.set:lua+del3.redisson:@Overridepublic void unlock(String lockKe ...
- noip复习——快速幂
\(a ^ n \bmod p\) \(a, p, n \leq 10^9\) 最普通的二进制拆分 #define LL long long LL qpow(LL a, LL n, LL p) { L ...
- 掌握提高 Web 应用的性能的方法 之 优化 PHP 和 Laravel
Laravel 有很多东西.但是快不是其中之一.让我们学习一些优化技巧,以加快运行速度! 自从 Laravel 诞生以来,没有一个 PHP 开发人员不受她的影响.他们是喜欢 Laravel 提供的快速 ...
- node.js 模拟自动发送邮件验证码
node.js 模拟自动发送邮件验证码 引言 正文 1. QQ邮箱设置 2. 安装nodemailer 3.配置信息 4.综合 5.讲解 结束语 引言 先点赞,再看博客,顺手可以点个关注. 微信公众号 ...
- idea github 上传项目
1.创建本地仓库,VCS-->Import into Version Control-->Create Git Repository... 在弹框中选中项目所在的位置,点击OK,此时项目文 ...
- MySQL · 性能优化 · MySQL常见SQL错误用法(转自-阿里云云栖社区)
作者:阿里云云栖社区链接:https://zhuanlan.zhihu.com/p/26043916来源:知乎著作权归作者所有,转载请联系作者获得授权. 前言 MySQL在2016年仍然保持强劲的数据 ...
- Jmeter 常用函数(21)- 详解 __char
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.htm 作用 根据给定的字符值转换成 Unicode ...
- 第4章 DDL数据定义
第4章 DDL数据定义 4.1 创建数据库 1)创建一个数据库,数据库在HDFS上的默认存储路径是/user/hive/warehouse/*.db. hive (default)> creat ...
- HDFS 2.X新特性
1 集群间数据拷贝 1.scp实现两个远程主机之间的文件复制 scp -r hello.txt root@hadoop103:/user/atguigu/hello.txt // 推 push scp ...
- install -M
[root@controller ~]# source admin-openrc [root@controller ~]# neutron ext-list +-------------------- ...