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

建设广告网站费用wordpress 用户是否登陆

建设广告网站费用,wordpress 用户是否登陆,搭建网站用什么软件,wordpress 自定义标题前言 作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。 代码同步更新到 github ,要是点个Star您就是我的神 目录 前言代理模式1.情景模拟1.1静态代理优点局限 1.2 动态代理 2.应用3.局限4.解决方…

前言

作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。

代码同步更新到 github ,要是点个Star您就是我的神

目录

  • 前言
  • 代理模式
    • 1.情景模拟
      • 1.1静态代理
        • 优点
        • 局限
      • 1.2 动态代理
    • 2.应用
    • 3.局限
    • 4.解决方案CGLIB
      • 踩坑注意!!

代理模式

代理模式是一种结构型设计模式。
对于代理模式,其实不难理解,就是甲乙双方在做一件事的时候,有一个中间人作为代理。
甲委托代理,代理和乙对接。生活中的例子就是租房、房东、中介的关系,租房和房东作为甲乙双方,通过中介完成业务。

在代码开发中,代理模式主要用于控制对对象的访问,通过中介,避免调用者和提供方法的对象直接接触。

1.情景模拟

代理模式的主要抽象思路就是:A和B的直接交互变为A和B通过C来交互。
在宝可梦没血的时候,我们会选择对其进行治疗,我们可以通过背包里的伤药(直接接触),或者宝可梦中心(通过代理)。
于是我们首先抽象出代理模式的第一个概念: Subject抽象主题——回血,以及Real Subject真实主题——实现类

/*** 休息的地方* 提供回血方法*/
public interface Rest {void heal();
}/*** 回血的具体实现类*/
public class RestImpl implements Rest{@Overridepublic void heal() {System.out.println("治疗...");}
}

宝可梦中心作为代理类,自然要先懂得业务,所以代理类也要实现对应的接口:

/*** 静态代理类*/
public class PokemonCenterProxy implements Rest{// 被代理的角色private Rest rest;public PokemonCenterProxy(Rest rest) {this.rest = rest;}@Overridepublic void heal() {System.out.println("在宝可梦中心...");rest.heal();}
}

1.1静态代理

这样,当主角(即程序调用者)想要回血的时候,我们可以直接找到宝可梦中心(代理类):

public class StaticProxyDemo {public static void main(String[] args) {// 真实主题RestImpl rest = new RestImpl();// 传入代理类PokemonCenterProxy pokemonCenterProxy = new PokemonCenterProxy(rest);// 代理类来执行方法pokemonCenterProxy.heal();}
}
在宝可梦中心...
治疗...

优点

可以发现,我们仍然调用了原有对象的heal()方法,但是我们在此基础上,完成了方法的扩展。
即我们在没有修改原有实现类的基础上,实现了新增执行前后的动作的功能,我们甚至可以:

    @Overridepublic void heal() {System.out.println("在宝可梦中心...");rest.heal();System.out.println("按摩SPA");}

可能大家看到这里就比较眼熟,这不可以实现日志功能吗?没错,我们可以在方法执行前后织入另外的行为。
这样做的局限也很明显。

局限

从代理类的代码可以看出,我提供了一个构造方法,传入Rest接口的实现类,这样避免了有新的实现类的时候要再写对应的新的静态代理类的情况。
这样做的问题在于,我们仍然把被代理类给暴露出来了,仍然要先new一个Rest的实现类。
其次,如果Rest接口的方法增多,作为继承了接口的静态代理类,仍要实现每个方法,可能之间有大量的冗余代码。

所以要解决以上局限,动态代理是个更好的选择。

1.2 动态代理

Java对动态代理提供了支持。
要实现动态代理,第一步是实现内置的InvocationHandler接口,重写Invoke方法

public class DynamicProxy implements InvocationHandler {private Rest rest;public DynamicProxy(Rest rest) {this.rest = rest;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("进入宝可梦中心");Object invoke = method.invoke(rest, args);System.out.println("售后服务");return invoke;}
}

基于反射,程序在运行途中获得了类的方法(invoke的参数中的method),方法的参数等信息。
被代理的类,运行的所有方法都被替换为这个invoke方法,真正执行原方法的逻辑是在method.invoke(rest, args);
所以这一行的前后,就可以写代理类在执行方法之前/之后的逻辑。

public class DynamicProxyDemo {public static void main(String[] args) {// 需要被代理的对象Rest rest = new RestImpl();// 以此创建代理类DynamicProxy dynamicProxy = new DynamicProxy(rest);ClassLoader classLoader = rest.getClass().getClassLoader();Rest o = (Rest) Proxy.newProxyInstance(classLoader, new Class[]{Rest.class}, dynamicProxy);o.heal();}
}

动态代理的核心就在于Proxy类,在动态代理中,创建真实对象的实例是通过Proxy的newProxyInstance方法。
其参数有三:

  • 类加载器:接口类的类加载器,直接调用api获取
  • 实现的接口的数组: new Class[]{...}是创建数组并赋值的语法,里面传入要实现的接口的类对象
  • 实现了InvocationHandler的对象,用来执行逻辑

然后用Proxy类创建出的对象调用方法,就可以实现代理类中实现的逻辑,无论Rest接口有多少方法,我们都不需要一一去实现。
相应地,有新业务接口的时候,也不用新增代理类。除非你有不同的代理逻辑(即invoke方法里的逻辑),否则都不需要新增代码。
运行结果:

进入宝可梦中心
治疗...
售后服务

2.应用

Spring框架中AOP就是基于动态代理,以此来实现一种切面逻辑。
应用场景包括:日志记录、权限控制。

3.局限

通过Proxy类来实现动态代理有一个最主要的局限:只能代理接口类。
并且通过反射来实现的性能开销比较大。

4.解决方案CGLIB

通过CGLIB实现动态代理。CGLIB可以实现对类的动态代理,并且实现原理是生成新的字节码类。
第一步:引入依赖

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>

第二部:写要代理的类(这里可以不是接口了)

public class Heal {public void heal(){System.out.println("HP+++");}
}

第三步:创建代理类

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {// 代理逻辑System.out.println("Pre");Object o1 = methodProxy.invokeSuper(o, objects);System.out.println("Suf");return o1;}
}

第四步:创建代理对象

public class Demo {public static void main(String[] args) {// 创建Enhancer类,类似于Proxy类Enhancer enhancer = new Enhancer();// 设置目标类enhancer.setSuperclass(Heal.class);// 设置拦截器enhancer.setCallback(new MyMethodInterceptor());// 创建代理对象Heal proxy = (Heal)enhancer.create();// 执行原有方法proxy.heal();}
}

踩坑注意!!

如果跟我一样用的Java17, 那么运行的时候会出现:

Exception in thread "main" java.lang.ExceptionInInitializerErrorat com.example.springbootdemo.proxyCglib.Demo.main(Demo.java:7)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @14899482at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)... 1 more

解决方法和原因: https://blog.csdn.net/guoshengkai373/article/details/127319933

只能换到低版本的JDK,我试过把CGLIB依赖版本弄到最新,也没用。

http://www.yayakq.cn/news/323391/

相关文章:

  • 潍坊网站定制网络工程师要考哪些证
  • 网站后台分模块wordpress淘客主题
  • 凯里官网品牌网站建设优化公司
  • 分销网站建设方案物联网工程是干什么的
  • 环球网最新新闻学校seo推广培训班
  • 企业网站翻译郑州专做喜宴的网站
  • 做eso哪家网站好为什么不能去外包公司
  • 排名好的网站建设网站站内优化方案
  • 模板网站建设教程php网站开发环境说明
  • 电商网站营销互联网推广培训机构
  • 图片做多的网站是哪个没有网站怎么做百度推广
  • 民治做网站的公司网站做的相似
  • 怎么样建设网站网站首页设计制作教程
  • 网站谁家做得好公司网站建设开发济南兴田德润优惠吗
  • 华为产品开发流程重庆seo教程
  • 现在外国有哪个网站可以做卖东西爱奇艺的网站是用什么做的
  • 那个网站做外贸最好建网站的公司
  • 影视怎么建设网站专业建站分销商城
  • 网站制作公司收费情况电商企业网站建设的一般要素有哪些
  • 自己做的网站怎么绑定域名安徽合肥
  • 西部数码的vps云主机如何访问网站输入网址一键生成app
  • 网站建设方案论文金融软件开发公司排名
  • 网站网站建设哪家便宜企业网络营销的意义
  • 织梦网站安装视频图片展示型网站模板下载
  • 国内html5网站案例专注高密做网站哪家好
  • 做门户网站用什么系统网站建设推广销售人员
  • 东莞最好的网站建设价格学习建设网站难么
  • 黑河做网站哪家好公众号接入小程序
  • 重庆网站备案大厅四川省住建厅官网
  • 互联网营销网站建设沈阳建设工程信息网官网新网站