Java开发两年了,连个java代理模式都摸不透,你怎么跳槽涨薪?

4、当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。(待论证)

5、当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。(待论证)

静态代理


静态代理要求代理类必须继承被代理对象的接口。相当于中介(代理类)知道房东(被代理对象)有哪几个方面的要求(方法)。

代码实现

房东接口

public interface ILandlord {

//出售

String sell(int price);

//出租

String lease(int leaseTime,int price);

}

复制代码

房东实现类

public class Landlord implements ILandlord {

String houseName;//房屋名称

int houseSellPrice;//房屋出售价格

int houseLeasePrice;//房屋出租价格(单价)

int houseLeaseTime;//最短出租时间

@Override

public String sell(int price) {

if(price>=houseSellPrice){

return “我同意以”+price+“元的价格出售”+houseName;

}else{

return “我不同意以”+price+“元的价格出售”+houseName;

}

}

@Override

public String lease(int leaseTime, int price) {

if(price<houseLeasePrice){

return “我不同意以”+price+“元的价格将”+houseName+“出租”;

}

if(leaseTime<houseLeaseTime){

return “我不同意将”+houseName+“出租”+leaseTime+“个月”;

}

return “我同意以”+price+“元的价格将”+houseName+“出租”+leaseTime+“个月”;

}

public Landlord() {

}

public Landlord(String houseName, int houseSellPrice, int houseLeasePrice, int houseLeaseTime) {

this.houseName = houseName;

this.houseSellPrice = houseSellPrice;

this.houseLeasePrice = houseLeasePrice;

this.houseLeaseTime = houseLeaseTime;

}

public String getHouseName() {

return houseName;

}

public void setHouseName(String houseName) {

this.houseName = houseName;

}

public int getHouseSellPrice() {

return houseSellPrice;

}

public void setHouseSellPrice(int houseSellPrice) {

this.houseSellPrice = houseSellPrice;

}

public int getHouseLeasePrice() {

return houseLeasePrice;

}

public void setHouseLeasePrice(int houseLeasePrice) {

this.houseLeasePrice = houseLeasePrice;

}

public int getHouseLeaseTime() {

return houseLeaseTime;

}

public void setHouseLeaseTime(int houseLeaseTime) {

this.houseLeaseTime = houseLeaseTime;

}

}

复制代码

中介类

public class Intermediary implements ILandlord {

private ILandlord obj;

Intermediary(ILandlord obj){

super();

this.obj=obj;

}

@Override

public String sell(int price) {

System.out.println(“中介将购房人的出价告知房东”);

String res = obj.sell(price);

System.out.println(“房东:”+res);

System.out.println(“中介将房东的结果告知购房人”);

return “房东:”+res;

}

@Override

public String lease(int leaseTime, int price) {

System.out.println(“中介将租房人的出价告知房东”);

String res = obj.lease(leaseTime,price);

System.out.println(“房东:”+res);

System.out.println(“中介将房东的结果告知租房人”);

return “房东:”+res;

}

}

复制代码

测试类

public class StaticProxyTest {

public static void main(String[] args) {

Landlord landlordA=new Landlord(“保利001号”,3000000,2000,6);

Intermediary proxy=new Intermediary(landlordA);

String res = proxy.sell(3010000);

System.out.println(“购房者得到的结果:”+res);

res = proxy.lease(5,1998);

System.out.println(“购房者得到的结果:”+res);

}

}

复制代码

结果

中介将购房人的出价告知房东

房东:我同意以3010000元的价格出售保利001号

中介将房东的结果告知购房人

购房者得到的结果:房东:我同意以3010000元的价格出售保利001号

中介将租房人的出价告知房东

房东:我不同意以1998元的价格将保利001号出租

中介将房东的结果告知租房人

购房者得到的结果:房东:我不同意以1998元的价格将保利001号出租

复制代码

JDK动态代理


JDK中的动态代理是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。JDK中的动态代理使用的是java.lang.reflect.Proxy中的newProxyInstance方法来实现。

newProxyInstance方法的三个参数是ClassLoader loader、Class<?>[] interfaces和InvocationHandler h。

ClassLoader loader:类加载器,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用。

Class<?>[] interfaces:指明被代理类实现的接口,之后我们通过拼接字节码生成的类才能知道调用哪些方法。

InvocationHandler h:这是一个方法委托接口,每个代理的实例都有一个与之关联的 InvocationHandler 实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的 InvocationHandler 实现类,由它的invoke方法决定处理。InvocationHandler 接口内部只是一个 invoke() 方法。

invoke方法的三个参数是Object proxy、 Method method和 Object[] args。

Object proxy:代理类实例。注意:这个代理类实例不是代理接口的实现类对象,而是JDK根据传入的接口生成一个extends Proxy implements Interface的代理类的对象。这个对象其实就是Proxy.newProxyInstance方法生成的对象(结尾处做验证)。

Method method:被调用的方法对象。

Object[] args:传入的方法参数。

代码实现


待代理的接口

public interface Star {

/**

  • 唱歌

  • @param song

  • @return

*/

String sing(String song);

/**

  • 演戏

  • @return

*/

String acting();

}

复制代码

接口的实现类

/**

  • 歌星

*/

public class SingingStar implements Star {

@Override

public String sing(String song) {

System.out.println(“明星本人表示愿意唱:《”+song+“》”);

return “愿意唱:《”+song+“》”;

}

@Override

public String acting() {

System.out.println(“明星本人表示不愿意演戏”);

return “不愿意演戏”;

}

}

复制代码

InvocationHandler接口实现类

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class DynamicsStarProxy implements InvocationHandler {

Object obj;

DynamicsStarProxy(Object obj){

this.obj=obj;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println(“动态明星代理和甲方协商出演的酬劳”);

Object res = method.invoke(obj, args);

System.out.println(“动态明星代理得到明星的决定,并告知甲方”);

return res;

}

}

复制代码

测试类

public class DynamicsProxyTest {

public static void main(String[] args) {

Star taylorSwift=new SingingStar();

DynamicsStarProxy starProxy=new DynamicsStarProxy(taylorSwift);

Star proxy= (Star) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),taylorSwift.getClass().getInterfaces(),starProxy);

//甲方找霉霉演唱Mean

String singRes=proxy.sing(“Mean”);

System.out.println(“甲方得到的结果:”+singRes);

//甲方又想找霉霉演戏

String actRes=proxy.acting();

System.out.println(“甲方得到的结果:”+actRes);

}

}

复制代码

结果

动态明星代理和甲方协商出演的酬劳

明星本人表示愿意唱:《Mean》

动态明星代理得到明星的决定,并告知甲方

甲方得到的结果:愿意唱:《Mean》

动态明星代理和甲方协商出演的酬劳

明星本表示不愿意演戏

动态明星代理得到明星的决定,并告知甲方

甲方得到的结果:不愿意演戏

复制代码

CGLib动态代理


Cglib是一个强大的,高性能,高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类,大部分功能实际上是ASM所提供的,Cglib只是封装了ASM,简化了ASM操作。GLib动态代理不要求被代理类实现接口,任何一个类都可以被轻松的代理(final类不能,final方法也不能)。

Cglib动态代理需要自定义实现MethodInterceptor接口,在代理对象调用方法时,会被拦截到intercept方法中。

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)

Object obj:cglib生成的代理对象,对应JDK动态代理中invoke方法的Object proxy。

Method method:被调用的代理对象方法,对应JDK动态代理中invoke方法的Method method。

Object[] args:方法入参,对应JDK动态代理中invoke方法的Object[] args。

MethodProxy proxy:被调用的方法的代理方法,CGLib动态代理通过该参数的invokeSuper方法来调用被代理对象的方法。

代码实现

maven依赖

cglib

cglib

3.3.0

复制代码

待代理的类

/**

  • 舞蹈名星

*/

public class DanceStar {

private String name;//艺名

//跳舞方法

public String dancing(String typeName){

System.out.println(name+“表示愿意跳”+typeName);

return name+“愿意跳”+typeName;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

DanceStar(){

super();

}

DanceStar(String name){

super();

this.name=name;

}

}

复制代码

Cglib代理类

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibStarProxy implements MethodInterceptor {

/**

  • 自定义方法:利用Enhancer类生成代理类

  • @param clazz

  • @param

  • @return

*/

public T getObjByEnhancer(Class clazz){

Enhancer enhancer=new Enhancer();

enhancer.setSuperclass(clazz);

enhancer.setCallback(this);

T res = (T) enhancer.create();

return res;

}

/**

  • 自定义方法:利用Enhancer类生成代理类(模拟JDK代理的用法)

  • @param target

  • @return

*/

private Object object;

public Object getObjByEnhancer(Object target){

this.object=target;

Enhancer enhancer=new Enhancer();

enhancer.setSuperclass(target.getClass());

enhancer.setCallback(this);

Object res = enhancer.create();

return res;

}

@Override

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
r enhancer=new Enhancer();

enhancer.setSuperclass(target.getClass());

enhancer.setCallback(this);

Object res = enhancer.create();

return res;

}

@Override

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-AziK6aFp-1715738344945)]

[外链图片转存中…(img-swLUmInL-1715738344946)]

[外链图片转存中…(img-ogcHnkK6-1715738344947)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值