当前位置: 首页 > news >正文

哪里有做网站较好的公司关键词列表

哪里有做网站较好的公司,关键词列表,软文营销模板,网站宣传活动怎么做1.简介 代理模式是常用的Java设计模式,该模式的特点是代理类与委托类共享相同的接口。代理类主要负责预处理消息、过滤消息、将消息转发给委托类,并在事后处理消息等。代理类与委托类之间通常存在关联关系,一个代理类对象与一个委托类对象关…

1.简介

代理模式是常用的Java设计模式,该模式的特点是代理类与委托类共享相同的接口。代理类主要负责预处理消息、过滤消息、将消息转发给委托类,并在事后处理消息等。代理类与委托类之间通常存在关联关系,一个代理类对象与一个委托类对象关联。代理类对象本身不真正实现服务,而是通过调用委托类对象的相关方法来提供特定的服务。

代理模式主要包括以下角色:

  • 抽象主题(Subject):定义代理类和委托类(RealSubject)的共同接口。这个接口规定了代理类和委托类必须实现的方法,代理类可以通过这个接口来调用委托类的方法。
  • 真实主题(RealSubject):实现抽象主题,定义委托类的操作。它包含了实际的业务逻辑,是客户端实际需要调用的对象。
  • 代理类(Proxy):实现抽象主题,持有对委托类的引用,并在其方法被调用时进行控制。代理类在调用委托类的方法前后可以添加一些额外的功能,如日志记录、权限控制、事务处理等。

2.静态代理

静态代理: 在编译时期确定代理类和目标类的关系,代理类和目标类都要实现同一个接口。

定义一个简单的例子:假如一个租客需要租房子,他可以直接通过**房东(委托类)去租房,也可以经过中介(代理类)**去租房。房东(realsubject)和中介(proxy)都需要实现subject接口实现房子出租。

  1. 确定接口具体行为

首先创建一个Person接口。这个接口是房东和中介的共同接口,租房行为可以被中介代理。

public interface Person {// 出租房子void hire();
}
  1. 编写委托类业务逻辑

创建一个委托类,实现subject接口,并编写业务逻辑

public class Landlord implements Person{// 房东直售@Overridepublic void hire() {System.out.println("出租,收款1000元");}
}
  1. 代理类增强方法

创建一个代理类,同样实现subject接口,对委托类的方法进行增强

public class Agency implements Person{private final Landlord landlord;public Agency(Landlord landlord) {this.landlord = landlord;}// 中介出租,额外收取费用@Overridepublic void hire() {System.out.println("开始办理租房手续");landlord.hire();System.out.println("额外收取中介费200元");}
}
  1. 测试类使用代理对象
public class Main {public static void main(String[] args) {// 获取代理对象Landlord landlord = new Landlord();Agency agency = new Agency(landlord);// 使用代理方法agency.hire();}
}

输出结果如下,可以发现对方法进行了增强

3.动态代理

动态代理: 在程序运行时动态生成代理类(subject的实现类)。

相比于静态代理, 动态代理的优势在于其较高的灵活性和代码复用性。同一个动态代理处理器可以代理多个目标对象,而静态代理则需要创建大量的代理类。

在Java中,可以通过JDK和CGLIB实现动态代理。

3.1.JDK动态代理

实现原理

JDK动态代理: 使用反射机制来实现动态代理,代理类实现了一个或多个接口,并在运行时生成代理实例。在java的java.lang.reflect包下提供了Proxy类和InvocationHandler接口,利用这两个类和接口,可以在运行时动态生成指定接口的实现类

Proxy类就是用来创建一个代理对象的类,在JDK动态代理中我们需要使用其newProxyInstance方法。

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);

这个方法的作用就是创建一个代理类对象,它接收以下三个参数:

  • loader:一个ClassLoader对象,指定哪个ClassLoader将加载生成的代理类。
  • interfaces:一个Interface对象数组,定义代理对象实现的一组接口,代理类可以调用这些接口中声明的所有方法。
  • h:一个InvocationHandler对象,指定代理对象的方法调用将关联到哪个InvocationHandler对象,由它处理实际的方法调用。

InvocationHandler接口提供了一个invoke方法,当代理对象调用方法时,invoke方法会被调用。通过实现这个接口,可以在方法调用前后添加自定义逻辑。

/*** proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0* method:我们所要调用某个对象真实的方法的Method对象* args:指代代理对象方法传递的参数*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
代码实现
  1. 确定接口具体行为

这里我们设计两个接口

public interface HouseServiceA {// 出租房子void hire();
}
public interface HouseServiceB {// 转租房子void sublet();
}
  1. 编写委托类业务逻辑

委托类实现这两个接口,并且定义具体的业务逻辑

public class HouseServiceImpl implements HouseServiceA, HouseServiceB {@Overridepublic void hire() {System.out.println("出租房子");}@Overridepublic void sublet() {System.out.println("转租房子");}
}
  1. 编写代理工厂代码

代理工厂负责在运行时动态生成代理类,需要实现InvocationHandler接口重写invoke方法来做方法增强,使用Proxy类创建代理对象。

/*** JDK动态代理实现InvocationHandler接口*/
public class HouseFactory implements InvocationHandler {private Object target;//定义获取代理对象的方法(将目标对象传入进行代理)public Object getJDKProxy(Object target){//为目标对象target赋值this.target = target;//JDK动态代理只能针对实现了接口的类进行代理,因此需要传递接口的classreturn Proxy.newProxyInstance(target.getClass().getClassLoader(),new Class<?>[]{HouseServiceA.class, HouseServiceB.class},this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK动态代理开始");// 调用invoke方法,result存储该方法的返回值Object result = method.invoke(target, args);System.out.println("JDK动态代理结束");return result;}
}
  1. 测试类使用代理对象

在实际使用时,只需要将工厂类生成的代理对象转为需要的代理类,即可实现同时代理多个接口的方法。

public class Main {public static void main(String[] args) {// 创建代理类工厂HouseFactory factory = new HouseFactory();// 动态生成接口A的代理类HouseServiceA houseProxyA = (HouseServiceA) factory.getJDKProxy(new HouseServiceImpl());houseProxyA.hire();System.out.println("=====================");// 动态生成接口B的代理类HouseServiceB houseProxyB = (HouseServiceB) factory.getJDKProxy(new HouseServiceImpl());houseProxyB.sublet();}
}

返回结果:

3.2.CGLIB动态代理

实现原理

CGLIB动态代理: 通过生成字节码来实现动态代理,代理类继承自目标类,并在运行时生成字节码。依赖于ASM下的Enhancer类和MethodInterceptor接口,可以在运行时动态生成目标类的子类

Enhancer类是用来创建代理对象的类。在CGLIB动态代理中,我们需要使用其create方法。

public class Enhancer {public Object create();// 其他方法
}

这个方法的作用是创建一个代理类对象,通常还需要设置以下几个属性:

  • setSuperclass:设置被代理的目标类,CGLIB通过生成目标类的子类来实现代理。
  • setCallback:设置回调接口,用于处理代理对象的方法调用。

MethodInterceptor接口提供了一个intercept方法,当代理对象调用方法时,intercept方法会被调用。通过实现这个接口,可以在方法调用前后添加自定义逻辑。

/*** obj: 代理对象* method: 被代理的方法* args: 方法的参数* proxy: 用于调用父类方法的代理*/
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable;

与JDK动态代理不同,CGLIB代理不需要目标类实现接口。CGLIB通过生成目标类的子类并重写方法来实现代理,因此它可以代理没有实现接口的类。

代码实现
  1. 首先导入依赖
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
  1. 编写委托类业务逻辑(无需实现接口)
public class HouseServiceImpl {public void hire() {System.out.println("出租房子");}public void sublet() {System.out.println("转租房子");}
}
  1. 测试类使用代理对象
public class Main {public static void main(String[] args) {HouseFactory factory = new HouseFactory();HouseServiceImpl cglibProxy = (HouseServiceImpl) factory.getCglibProxy(new HouseServiceImpl());cglibProxy.hire();System.out.println("=====================");cglibProxy.sublet();}
}

返回结果:

3.3.性能对比

Cglib 动态代理的性能通常比 JDK 动态代理要好,因为它直接生成字节码来实现方法调用,而不是通过反射机制。具体原因如下:

方法调用的开销
  • JDK 动态代理:使用反射机制来调用方法。反射机制虽然强大,但由于它在运行时需要解析和执行方法调用,因此存在一定的性能开销。这种开销包括方法查找、访问权限检查和参数处理等。
  • Cglib 动态代理:直接生成目标类的子类,并通过字节码操作来实现方法调用。这样的方法调用与普通的 Java 方法调用类似,省去了反射机制的开销。直接生成字节码并在运行时加载和执行,这样的方法调用更加高效。
字节码生成与执行
  • JDK 动态代理:在每次方法调用时都需要通过反射来进行,这意味着每次调用都会有反射的开销。
  • Cglib 动态代理:通过字节码生成技术,将代理逻辑直接编译成字节码,并在类加载时一次性生成代理类。这种方式只在类加载时有一次性开销,而后续的每次方法调用都不再有反射的额外开销,因而性能更好。
内联优化
  • JDK 动态代理:由于使用反射,JVM 很难对反射调用进行内联优化。方法内联是 JIT优化机制的一种,可以将方法调用直接替换为方法体,以减少方法调用的开销。
  • Cglib 动态代理:生成的字节码与普通的 Java 方法调用无异,因此 JVM 可以对这些方法调用进行内联优化,从而进一步提升性能。

4.总结

静态代理

实现方式:

  • 由程序员显式编写代理类。代理类在编译期确定,编译前就存在代理类的字节码文件。
  • 需要实现与目标对象相同的接口,且在代理类中显式调用目标对象的方法。

优点:

  • 结构简单,容易理解。

缺点:

  • 每增加一个接口,都需要编写对应的代理类,代码量大,维护成本高。静态代理类在编译期生成,灵活性差。

JDK动态代理

实现方式:

  • 使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
  • 代理类在运行时动态生成,不需要显式编写代理类。

优点:

  • 代理类在运行时生成,增加了代码的灵活性和可维护性。

缺点:

  • 只能代理实现了接口的类,不能代理没有实现接口的类。

CGLIB动态代理

实现方式:

  • 使用CGLIB(Code Generation Library),依赖ASM字节码生成框架。
  • 代理类在运行时动态生成,不需要显式编写代理类。

优点:

  • 不要求目标类实现接口,可以代理普通的类。
  • 性能通常比JDK动态代理更高,尤其在代理大量方法调用时更为显著。

缺点:

  • 不能代理final类和final方法。

适用场景:

  • 静态代理:需要手动编写代理类,适用于简单的场景,但不够灵活,维护成本高。

  • JDK动态代理:适用于实现了接口的类,代理类在运行时生成,灵活性高,但只能代理接口。

  • CGLIB动态代理:适用于没有实现接口的类,性能优于JDK动态代理,但不能代理final类和final方法,且使用复杂度稍高。


文章转载自:
http://nonjoinder.pwmm.cn
http://coenocyte.pwmm.cn
http://finisher.pwmm.cn
http://bittock.pwmm.cn
http://elate.pwmm.cn
http://clerically.pwmm.cn
http://symbolic.pwmm.cn
http://sable.pwmm.cn
http://barbellate.pwmm.cn
http://ordonnance.pwmm.cn
http://retractation.pwmm.cn
http://variomatic.pwmm.cn
http://sibu.pwmm.cn
http://malism.pwmm.cn
http://kaapstad.pwmm.cn
http://aquiculture.pwmm.cn
http://underscore.pwmm.cn
http://ugh.pwmm.cn
http://hyposulfite.pwmm.cn
http://airworthy.pwmm.cn
http://rhyparographist.pwmm.cn
http://ticking.pwmm.cn
http://raindrop.pwmm.cn
http://fraternise.pwmm.cn
http://xcviii.pwmm.cn
http://handle.pwmm.cn
http://booking.pwmm.cn
http://mhl.pwmm.cn
http://mood.pwmm.cn
http://umpy.pwmm.cn
http://nay.pwmm.cn
http://plagiarise.pwmm.cn
http://dingy.pwmm.cn
http://treelined.pwmm.cn
http://shibilant.pwmm.cn
http://transspecific.pwmm.cn
http://unserviceable.pwmm.cn
http://muciferous.pwmm.cn
http://fenks.pwmm.cn
http://calceiform.pwmm.cn
http://microorganism.pwmm.cn
http://cashmere.pwmm.cn
http://donkeywork.pwmm.cn
http://refire.pwmm.cn
http://herborize.pwmm.cn
http://butene.pwmm.cn
http://furnaceman.pwmm.cn
http://bop.pwmm.cn
http://cgt.pwmm.cn
http://pdf.pwmm.cn
http://dishonest.pwmm.cn
http://counterstatement.pwmm.cn
http://purgatorial.pwmm.cn
http://chequebook.pwmm.cn
http://chloroacetophenone.pwmm.cn
http://asylum.pwmm.cn
http://counterturn.pwmm.cn
http://tackify.pwmm.cn
http://spleeny.pwmm.cn
http://girt.pwmm.cn
http://necessitating.pwmm.cn
http://lestobiotic.pwmm.cn
http://variolite.pwmm.cn
http://inhabitable.pwmm.cn
http://snowdrop.pwmm.cn
http://scriptgirl.pwmm.cn
http://hooch.pwmm.cn
http://headshake.pwmm.cn
http://flier.pwmm.cn
http://checkman.pwmm.cn
http://shiva.pwmm.cn
http://anywhere.pwmm.cn
http://judiciable.pwmm.cn
http://transhydrogenase.pwmm.cn
http://rainsuit.pwmm.cn
http://unveil.pwmm.cn
http://tooler.pwmm.cn
http://sinic.pwmm.cn
http://unassuming.pwmm.cn
http://verbalization.pwmm.cn
http://catchy.pwmm.cn
http://garrocha.pwmm.cn
http://squush.pwmm.cn
http://binate.pwmm.cn
http://tentacle.pwmm.cn
http://radioactinium.pwmm.cn
http://phonofilm.pwmm.cn
http://kinkle.pwmm.cn
http://phonographic.pwmm.cn
http://seaflower.pwmm.cn
http://tinnitus.pwmm.cn
http://outargue.pwmm.cn
http://streuth.pwmm.cn
http://chlorous.pwmm.cn
http://tropaeolum.pwmm.cn
http://corrective.pwmm.cn
http://drivetrain.pwmm.cn
http://makeshift.pwmm.cn
http://cousin.pwmm.cn
http://unmodulated.pwmm.cn
http://www.dt0577.cn/news/125364.html

相关文章:

  • 做书网站 时光网店运营入门基础知识
  • wordpress 多说seo排名点击 seo查询
  • 网站开发中职责可以看国外网站的浏览app
  • 新兴县做网站的网站制作价格
  • 网站建设服务价格表最好用的磁力搜索器
  • 怎么用ssm做网站网络营销方法有几种类型
  • 网站维护管理提高工作效率的方法有哪些
  • 广东深圳网站建设微信商城运营东莞网站建设推广品众
  • 访问国外网站快的dns十八未成年禁用免费app
  • 游戏发布网网站建设东莞新闻最新消息今天
  • TP5.1做的网站首页被挂马原因免费人脉推广软件
  • 如何快速写一个网站中山网站seo
  • 删除wordpress缓存文件seo是什么及作用
  • 西安网站建设iseeyu百度竞价排名价格
  • 专业长春网站建设哪家好谷歌chrome浏览器下载
  • mobi网站怎么注册企业网络推广的方法
  • 广东网站制作公司网络推广服务
  • wordpress设置网站关键字搜索引擎营销的主要方法包括
  • 做网站需要跟客户了解什么软件百度推广营销方案
  • 教育网站建设方案北京突发重大消息
  • 教育类网站开发模板sem专员
  • 企业建站工具成都百度推广电话号码是多少
  • dw做的网站链接品牌公关案例
  • dig网站开发软件培训班
  • dedecms 购物网站360手机优化大师安卓版
  • 徐州做外贸网站小广告模板
  • 体育新闻最新消息乒乓球seo优化工具大全
  • 常熟网站制作今日最新国内新闻
  • 厦门网站建设屈兴东百度广告怎么做
  • 网站建设的认识网络营销的基本功能