追溯

学一个技术,要知道技术因何而产生,才能有学下去的目标和动力,才能更好的理解

首先,要明确为什么要存在代理呢?

存在一个常见的需求:怎样在不修改类A代码的情况下,在调用类A的方法时进行一些功能的附加与增强呢?

先不考虑什么代理不代理的,我们设计一个简单的实现方案:

新创建一个类B,类B组合类A,在类B中创建一个方法b,方法b中调用类A中的方法a,在调用前和调用后都可以添加一些自定义的附加与增强代码。 当有需求需要调用类A的方法a并且想要添加一个附加功能时,就去调用类B的方法b即可实现上述需求;

下面为了便于理解,附上伪代码:

// 定义类A
public class  ClassA{public void methoda(){System.out.println("我是方法a!");}
}// 定义类B
public class ClassB{// 组合ClassAClassA  A;public ClassB(ClassA A){this.A = A;}@Overridepublic void methodb(){System.out.println("我是方法a的附加功能代码,我执行啦~!");A.methoda();System.out.println("我是方法a的附加功能代码,我完成啦~!");}
}

下面,让我们来调用一下ClassB的methodb方法,则会产生以下输出:

我是方法a的附加功能代码,我执行啦~!
我是方法a!
我是方法a的附加功能代码,我完成啦~!

可以发现,方法a执行了,并且在没有修改类A代码的前提下,为方法a附加了其他的功能;
不难吧,其实上述的代码就是一个最简单的代理模式

代理存在的意义:使用代理模式可以在不修改别代理对象代码的基础上,通过扩展代理类,进行一些功能的附加与增强

代理种类

代理分为静态代理动态代理,其涉及的设计模式就是代理模式本尊了,代理模式一般包含几种元素,如下图:
在这里插入图片描述

  1. 主题接口(subject):定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法;
  2. 真实主题(RealSubject):真正实现业务逻辑的类;
  3. 代理类(Proxy):用来代理和封装真实主题;
  4. 客户端(Client):使用代理类和主题接口完成一些工作。

为了更好的理解,我们将上述实现的最简易版的代理完善一下,添加接口,代理类也实现相应的被代理类的接口,实现同一个方法,伪代码如下:

// 被代理类的接口(上图中subject)
public interface ImpA{void methoda();
}
// 定义类A(上图中RealSubject)
public class  ClassA implements ImpA{public void methoda(){System.out.println("我是方法a!");}
}// 定义类B(上图中Proxy)
public class ClassB implements  ImpA {// 组合ClassAImpA  A;public ClassB(ClassA A){this.A = A;}// 重写被代理类的方法@Overridepublic void methoda(){System.out.println("我是方法a的附加功能代码,我执行啦~!");A.methoda();System.out.println("我是方法a的附加功能代码,我完成啦~!");}
}
// 客户端类(上图中Client)
public class Main{// 创建被代理对象实例ImpA A = new ClassA();// 构造器注入被代理对象实例ImpA B = new ClassB(A);// 调用代理方法B.methoda();
}

静态代理

所谓静态代理也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
上面的代码就是实现了一个静态代理; 其实静态代理就已经能够满足上述需求了,为什么还需要动态代理呢? 这里就涉及到静态代理的两个缺点了

  1. 代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,在程序规模稍大时静态代理代理类就会过多会造成代码混乱
  2. 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法,增加了代码维护的复杂度。
    基于上述两个问题,动态代理诞生了~

动态代理

动态代理是在程序运行时,通过反射获取被代理类的字节码内容用来创建代理类

具体什么是动态代理呢?
名词:动态,动态在程序中就是表达在程序运行时就根据配置自动的生成代理类并且代理类和被代理类是在运行时才确定相互之间的关系;

在JDK中包含两种动态代理的实现机制:JDK ProxyCGLib

下面我们以JDK Proxy为例,讲解一下动态代理和根据源码分析并简单说一下应用场景

JDK Proxy

JDK Proxy动态代理,api在包java.lang.reflect下,大家可能发现了,为什么在反射的包下呢?这个问题我们下面的源码分析会解决;

其核心api包含两个重要的核心接口和类:一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),简单说就这两个简单的很,这两个是我们实现动态代理所必需的用到的,下面简单介绍一下两个类:
java.lang.reflect.Proxy(Class) :Proxy是 Java 动态代理机制的主类,提供一组静态方法来为一组接口动态地生成代理类及其对象。包含以下四个静态方法:

  • static InvocationHandler getInvocationHandler(Object proxy)
    该方法用于获取指定代理对象所关联的调用处理器
  • static Class getProxyClass(ClassLoader loader, Class[] interfaces)
    该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
  • static boolean isProxyClass(Class cl)
    该方法用于判断指定类对象是否是一个动态代理类
  • static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h)
    该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例,包含下面的参数:
    • loader 指定代理类的ClassLoader加载器
    • interfaces 指定代理类要实现的所有接口
    • h: 表示的是当这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例

java.lang.reflect.InvocationHandler(interface)InvocationHandler是上述newProxyInstance方法的InvocationHandler h参数传入,负责连接代理类和委托类的中间类必须实现的接口
它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。

上述就是动态代理两个核心的方法,不太明白?先别急,我们先用上述实现一个动态代理,你先看一下

还是以上述的案例从静态代理来改造为动态代理,实现动态代理主要就两步,假设还是存在上述的ImplA、ClassA

1:创建一个处理器类实现InvocationHandler接口,重写invoke方法,伪代码如下:

public class MyHandler implements InvocationHandler{// 标识被代理类的实例对象private Object delegate;   // 构造器注入被代理对象public MyHandler(Object delegate){this.delegate = delegate;}// 重写invoke方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("被代理方法调用前的附加代码执行~ ");// 真实的被代理方法调用method.invoke(delegate, args);System.out.println("被代理方法调用后的附加代码执行~ ");} 
}

好了,这样一个处理器就搞定了,当我们在调用被代理类的方法时,就是去执行上述重写的invoke方法,下面创建一个ClassA的代理类

2:创建代理类,并调用被代理方法

public class MainTest{public static void main(String[] args) {    // 创建被代理对象ImplA A = new ClassA();// 创建处理器类实现InvocationHandler myHandler = new MyHandler(A);// 重点! 生成代理类, 其中proxyA就是A的代理类了ImplA proxyA = (ImplA)Proxy.newProxyInstance(A.getClass().getClassLoader(), A.getClass().getInterfaces(), myHandler);// 调用代理类的代理的methoda方法, 在此处就会去调用上述myHandler的invoke方法区执行,至于为什么,先留着疑问,下面会说清楚~proxyA.methoda();}
}

好了,至此一个动态代理就构建完成了,执行代码,会发现输出:

被代理方法调用前的附加代码执行~
我是方法a!
被代理方法调用后的附加代码执行~

太简单了有木有,这里总结一下动态代理的优缺点:

优点:

  1. 动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。

  2. 动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。

  3. 接口增加一个方法,除了所有实现类需要实现这个方法外,动态代理类会直接自动生成对应的代理方法。

缺点:
JDK proxy只能对有实现接口的类才能代理,也就是说没有接口实现的类,jdk proxy是无法代理的,为什么呢?下面会解答.

有什么解决方案吗? 当然有,还有一种动态代理的方案:CGLib,它是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,对于final类或方法,是无法继承的,和jdk proxy基本思想是相似的,毕竟都是动态代理的实现方案嘛,在这篇文章就不做详解了,博主会在其他的博文单独介绍这个nb的框架

上述带大家搞了一遍动态代理和静态代理的应用;在这过程中,你有没有想过,动态代理是怎么实现的呢?

下面我们就从源码的角度分析一下,解决大家的疑问。

源码分析

在开始分析的时候,我希望大家带着几个问题去阅读,可以帮助大家更好的理解:

  • 问题1:代理类为什么可以在运行的时候自动生成呢?如何生成的呢?
  • 问题2:为什么调用代理类的相应的代理方法就可以调用到InvocationHandler实现类的invoke方法呢?
  • 问题3:为什么jdk proxy只支持代理有接口实现的类呢?

ps :为了提升阅读体验,让大家有一个更清晰的认知,以下源码会将一些异常处理和日志打印代码删除,只保留主干代码,请知悉~

我们就从两个核心:InvocationHandlerProxy来进行分析整个脉络,他们都在java.lang.reflect包下

InvocationHandler源码

public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}

上述就是InvocationHandler的源码,没什么其他的就是一个接口,里面有一个待实现方法invoke,处理类实现此接口重写invoke方法

Proxy源码

public class Proxy implements java.io.Serializable {// 处理类实例 变量protected InvocationHandler h;// 用于存储 已经通过动态代理获取过的代理类缓存private static final WeakCache<ClassLoader, Class<?>[], Class<?>>  proxyClassCache = new WeakCache<>(new KeyFactory(),new ProxyClassFactory());// 私有无参构造,使得只能通过传入InvocationHandler参数来创建该对象private Proxy() {}// 保护 构造函数,入参InvocationHandler处理类protected Proxy(InvocationHandler h) {Objects.requireNonNull(h);this.h = h;}public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces) throws IllegalArgumentException{...}public static boolean isProxyClass(Class<?> cl) {...}public static InvocationHandler getInvocationHandler(Object proxy)  throws IllegalArgumentException {...}// 生成代理类的实现方法public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException{...}// 各种私有方法private ... ...
}

Proxy类的整体的架构就类似于上述,InvocationHandler h参数和两个构造函数四个上述已经介绍过的共有方法,还有一系列的私有方法,getProxyClass、isProxyClass、getInvocationHandler功能就和上面介绍的一样,就不再详细介绍了

我们下面来主要看一下newProxyInstance方法
newProxyInstance方法,我在方法内添加上了对应的注释:

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException{// 1. 克隆对应的接口,用于代理类实现的接口数组final Class<?>[] intfs = interfaces.clone();.../** Look up or generate the designated proxy class.  源码中的介绍* 2. 查找或者生成指定的代理类, 下面会详细介绍*/Class<?> cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.* 3. 上面代码已经生成了代理类 cl,cl其中包含一个参数为传入的InvocationHandler h的构造函数, 获取该构造函数并通过该构造函数创建一个类的实例对象并返回*/try {// 4. 通过《反射》获取参数为InvocationHandler的构造函数final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;// 5. 判断构造函数是否为私有的,如果为私有的则需要设置私有可访问权限if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {cons.setAccessible(true);return null;}});}// 6. 通过上述获取的构造函数创建对应的 实例对象,并返回!over~return cons.newInstance(new Object[]{h});} catch (IllegalAccessException|InstantiationException e) {// 各种异常处理}}

在上面的代码中,我简单的标注了一下每行代码的作用,下面我们来详细分析一下;

代理类的字节码生成逻辑

我们知道,在加载jvm前,java文件都已经被编译成了class字节码文件, 然后jvm通过类加载器将字节码文件加载到jvm中;

我们的代理类也是这样,不同的是动态代理的类是在程序运行时产生的,我们要做的就是如何在程序运行的时候,通过被代理类的字节码生成代理类的字节码!

我们接下来详细分析newProxyInstance方法:

在newProxyInstance中调用了Class<?> cl = getProxyClass0(loader, intfs);语句生成了代理类的字节码,此处调用了getProxyClass0方法,传入了指定的类加载器和对应要实现的接口

那么, 我们看看getProxyClass0方法的实现:

    private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");}// proxyClassCache是WeakCache弱引用缓存类,如果之前就生成过对应的代理类就从缓存中取,如果没生成过就重新生成return proxyClassCache.get(loader, interfaces);}

proxyClassCache是Proxy类中的静态变量,是WeakCache类,里面封装了两个类KeyFactory、ProxyClassFactory,都是BiFunction函数式接口(如果不清楚函数式接口,请自行google);

将其拿过来看一下proxyClassCache = new WeakCache<>(new KeyFactory(),new ProxyClassFactory()); 其中调用了proxyClassCache.get(loader, interfaces)方法的实现

未避免代码过长,只粘贴了核心代码:

   public V get(K key, P parameter) {...// 这部分主要是获取对应的 函数式接口,如果不明白函数式接口,google一下吧~Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));Supplier<V> supplier = valuesMap.get(subKey);Factory factory = null;while (true) {  // 此处为什么是while循环呢, 主要是supplier不为空的话,则执行下面的语句赋值后,再循环执行下一次则supplier不为空if (supplier != null) {// 如果存在对应的函数式接口,  调用函数式接口对应的代码// 重点!!!调用函数式接口!!V value = supplier.get();if (value != null) {return value;}}if (factory == null) {// 创建一个 专门创建代理类字节码的工厂类,实现类是ProxyClassFactoryfactory = new Factory(key, parameter, subKey, valuesMap);}if (supplier == null) {supplier = valuesMap.putIfAbsent(subKey, factory);if (supplier == null) {// 将supplier赋值factorysupplier = factory;}}}} }

总结一下上述方法的流程:

缓存中获取代理类字节码
是否存在
代理中获取并返回
调用ProxyClassFactory的apply方法生成代理类字节码

接着ProxyClassFactory.apply方法看一下:

       public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);// 获取接口对应的接口class对象for (Class<?> intf : interfaces) {Class<?> interfaceClass = null;try {interfaceClass = Class.forName(intf.getName(), false, loader);} if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { }}String proxyPkg = null;int accessFlags = Modifier.PUBLIC | Modifier.FINAL;// 判断是否包含公有的接口对象,判断是否可以通过jdk proxy的方式进行生成代理类for (Class<?> intf : interfaces) {int flags = intf.getModifiers();if (!Modifier.isPublic(flags)) {accessFlags = Modifier.FINAL;String name = intf.getName();int n = name.lastIndexOf('.');String pkg = ((n == -1) ? "" : name.substring(0, n + 1));if (proxyPkg == null) {proxyPkg = pkg;} else if (!pkg.equals(proxyPkg)) {}}}// 如果没有公有接口类,需要使用CGLib来实现。。。if (proxyPkg == null) {proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";}// 组装代理类的类名称long num = nextUniqueNumber.getAndIncrement();String proxyName = proxyPkg + proxyClassNamePrefix + num;// 重点!! 此处生成代理类的字节码数组byte[] proxyClassFile = ProxyGenerator.generateProxyClassproxyName, interfaces, accessFlags);try {// 通过类加载器将字节码数组加载到JVm的方法区中生成Class对象!return defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);} catch (ClassFormatError e) {}}

上述的byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags); 为生成代理类字节码数组的方法,调用的方法中调用了generateClassFile方法;

private byte[] generateClassFile() {// 首先,默认代理的三个方法:hashCode\equals\toStringthis.addProxyMethod(hashCodeMethod, Object.class);this.addProxyMethod(equalsMethod, Object.class);this.addProxyMethod(toStringMethod, Object.class);// 获取所有的要被代理类实现的接口Class[] var1 = this.interfaces;int var2 = var1.length;int var3;Class var4;// 遍历上述获取的接口for(var3 = 0; var3 < var2; ++var3) {// 赋值: 将接口的Class对象赋值!var4 = var1[var3];// 通过“反射”获取所有方法Method[] var5 = var4.getMethods();int var6 = var5.length;for(int var7 = 0; var7 < var6; ++var7) {Method var8 = var5[var7];// 将方法添加到 要被代理的方法中this.addProxyMethod(var8, var4);}}// 获取要代理方法后,开始组装字节码var14.writeInt(-889275714);var14.writeShort(0);var14.writeShort(this.accessFlags);var14.writeShort(this.cp.getClass(dotToSlash(this.className)));// 注意!!!  .... 此处省略了绝大部分 字节码的组装过程,只给出了几行代码展示一下字节码的组装// 最终返回组装好的字节码文件return var13.toByteArray();}}

generateClassFile中,你会发现里面全部是重组字节码的代码, 主要是获取被代理类字节码和操作类InvocationHandler字节码组装出代理类的字节码,在重组的过程因为是在运行时进行了代理类的创建,无法像往常一样new一个被代理类的实例获取他的方法,让代理类进行调用。

获取字节码后,接下来就要将代理类的字节码加载进JVM中了,这里调用的是一个return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length) 其中的defineClass0是一个本地native 方法,传入了代理类名称、类加载器、代理类的字节码文件、文件长度参数,从而将字节码加载进JVM中! 代码如下:

private static native Class<?> defineClass0(ClassLoader loader, String name,byte[] b, int off, int len);

将代理类的字节码加载进JVM后,会在方法区内生成一个Class对象,标识这个代理类;

代理类的实例生成逻辑
上面,我们知道了通过字节码技术生成了代理类字节码,并通过类加载器将字节码文件加载到了JVM的方法区中生成了一个Class对象,我们如何在运行时获取这个Class对象的实例呢? 只有获取了对象实例才可以使用不是~
还是回到newProxyInstance方法中,上面我们分析了Class<?> cl = getProxyClass0(loader, intfs)这部分逻辑,生成了Class对象cl,下面生辰该实例代码,过程很简单,相关逻辑我就直接在代码中注释了

    // 定义构造函数的参数类型,下面的一个语句使用private static final Class<?>[] constructorParams =    { InvocationHandler.class };// 通过反射获取上述获取的Class对象的带参构造函数,参数必须是上述定义的 InvocationHandler.class类型final Constructor<?> cons = cl.getConstructor(constructorParams);// 检查权限,如果是私有权限,设为可被访问if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {cons.setAccessible(true);return null;}});}// 通过构造函数传入对应 处理类h 参数,生成实例!return cons.newInstance(new Object[]{h});

上述就是生成实例的代码,生成实例后newProxyInstance就返回该实例了,就可以使用了~

反射:在运行时获取被代理类的字节码

那如何才能在运行时获取到被代理类的构造函数、方法、属性等字节码呢? 此时“反射!”登场了!我们通过反射可以在运行时获取到类的所有信息,所有哦。
定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

比如,在上述所说的组装代理类字节码时,在获取被代理类的所有方法时,就调用了Method[] var5 = var4.getMethods(); 反射中的getMethods方法,通过反射获取到了被代理类的所有方法,这样我们就可以在运行时获取到任何类的所有的字节码信息了! 从而可以组装出我们想要的代理类字节码!

所以说,反射也为动态代理的实现提供了理论支持!!因为只有在运行时能获取到对应类的信息,才可以通过信息创造出对应的我们所需要的代理类;

源码分析总结

总而言之,动态代理的理论支持是可以通过反射机制运行时获取到类的所有信息,如果运行时获取不到被代理类的信息,那还咋生成代理类。
动态代理的大致流程:

反射获取被代理字节码
反射获取InvocationHandler实现类字节码
依据被代理类字节码和InvocationHandler实现类字节码 通过操作字节码组装 代理类 字节码
通过给定的classLoad将 代理类字节码 加载到JVM中
调用native方法 加载到JVM的方法区 生成Class对象
反射获取代理类的Class对象的构造函数
通过反射获取的构造函数new一个代理类的实例A
使用代理类实例A

通过上述流程。我们就获得了一个代理类对象了,调用代理类对应的方法,就会执行我们规定的执行逻辑,实现对被代理类的运行时动态增强和扩展!

此时,我们再拿出刚开始我们用JDK proxy实现的动态代理代码中的生成代理类的代码:ImplA proxyA = (ImplA)Proxy.newProxyInstance(A.getClass().getClassLoader(), A.getClass().getInterfaces(), myHandler) 每个参数的作用,是不是就很清晰了

问题解答

上面动态代理实现流程,我们可以回答上述的第一个代理类为什么可以在运行的时候自动生成呢?如何生成的呢? 问题了

对于第二个为什么调用代理类的相应的代理方法就可以调用到InvocationHandler实现类的invoke方法呢?和第三个为什么jdk proxy只支持代理有接口实现的类呢?问题,我们需要反编译一下我们通过字节码技术产生的代理类,如下:

final class $Proxy0 extends Proxy implements ImplA {private static Method m1;private static Method m3;private static Method m2;private static Method m0;static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m3 = Class.forName("com.test.ImplA").getMethod("methoda");m2 = Class.forName("java.lang.Object").getMethod("toString");m0 = Class.forName("java.lang.Object").getMethod("hashCode");} catch (NoSuchMethodException var2) {// ..}}public $Proxy0(InvocationHandler var1) throws  {super(var1);}// 需要被加强的方法methodapublic final void methoda() throws  {try {super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean equals(Object var1) throws  {// 省略部分代码。。。return (Boolean)super.h.invoke(this, m1, new Object[]{var1});}public final String toString() throws  {// 省略部分代码。。。return (String)super.h.invoke(this, m2, (Object[])null);}public final int hashCode() throws  {// 省略部分代码。。。return (Integer)super.h.invoke(this, m0, (Object[])null);}
}

上述代码包含几个关键点:

  1. 方法为final类型,不可再被继承
  2. 代理名称为 $Proxy 代理类前缀 + 递增数字
  3. 继承动态代理的核心类Proxy, 实现了我们指定的接口ImplA
  4. 一个带参构造方法$Proxy0(InvocationHandler var1) 传入InvocationHandler内部调用了父类的Proxy的构造函数
  5. methoda、toString、hashCode、equals全部调用的传入的InvocationHandler参数的 invoke方法!!!

现在回答第二个问题为什么调用代理类的相应的代理方法就可以调用到InvocationHandler实现类的invoke方法呢?

显而易见,代理类内部的代理方法全部显式调用的InvocationHandler实现类的invoke方法

第三个问题为什么jdk proxy只支持代理有接口实现的类呢?

因为代理类在使用JDK proxy方式生成代理类时,默认继承Proxy类,又因为java语言是单继承不支持多继承,那怎样才能标识我要代理什么类型的类或是代理什么方法呢? 接口呗,java支持接口的多继承,多少个都ok~

好了,上述将动态代理的使用方式 和 实现原理统一过了一遍,也回答了几个容易疑惑的问题,下面我们简单说下动态代理在现实的java框架大家庭中的一些典型应用

动态代理的应用

spring aop : 这可以说是spring框架中最典型的应用了,通过动态代理在运行时产生代理类,完成对被代理类的增强和功能附加
RPC框架的实现 : 远程过程调用,RPC使得调用远程方法和调用本地方法一样,这是怎么搞的呢?服务方对外放出服务的接口api,调用方拿到接口api,通过动态代理的方式生成一个代理类,代理类的处理类的invoke方法可以通过websocket连接远程服务器调用对应的远程接口; 这样我们再用代理对象进行调用对应方法时时,就像调用本地方法一样了
mybatis框架中 : mapper.xml中编写sql语句,mapper.java接口写上对应的方法签名;我们直接调用mapper.java中的方法就可以执行对应的sql语句,有没有想过为什么? 框架使用动态代理创建一个mapper.java的代理对象,代理对象的处理类invoke中执行sql,就ok了

总结

代理分为静态代理动态代理,动态代理的两种实现方式:JDK ProxyCGLib,动态代理的核心反射机制,通过反射在运行时获取被代理类字节码和处理类字节码,动态代理代理类的生成通过重组字节码的方式。

原创不易,有收获的话,关注点赞评论三连支持,我最大的动力~

关于博文有任何问题请不吝评论,感谢

参考:JDK源码,https://www.jianshu.com/p/861223789d53

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 安装AZ SZ工具和siege实战练习记录

    siege实战练习 1、使用siege对多个页面进行加压步骤1:在本地添加一个txt文件,文件命名:urls.txt,并放在SecureCRT设置的文件目录下步骤2:在服务器上创建一个文件夹用来存放文件,命令:mkdir seigetext,创建文件夹后使用命令cd seigetext 进入文件夹目录下步骤3:上传urls.…...

    2024/4/15 7:56:44
  2. GreenDao 的简介和使用

    greenDAO简介 greenDAO是一款开源的面向 Android 的轻便、快捷的 ORM 框架,将 Java 对象映射到SQLite数据库中,我们操作数据库的时候,不再需要编写复杂的 SQL语句, 在性能方面,greenDAO针对 Android 进行了高度优化, 最小的内存开销 、依赖体积小 同时还是支持数据库加密…...

    2024/4/17 2:17:53
  3. redis搭建三主三从(两台机器)

    准备环境centos 7 192.168.136.202 192.168.136.165 1,安装环境,工具 [root@bogon ~]# yum -y install gcc gcc-c++2,创建下载目录 [root@bogon ~]# mkdir -p /redis/data3,进入目录,下载redis并解压进行编译安装 redis下载网址:http://download.redis.io/releases/redi…...

    2024/4/17 2:18:17
  4. SAI绘制月下狼嚎图

    最终效果图1.使用钢笔图层的曲线工具配合圆尺画出线稿,颜色#4C4C4C2.在钢笔图层使用魔棒工具选取狼和石头,滚动鼠标放大,看哪里漏选就多点一下选取,创建图层(狼影),使用油漆桶铺色#4C4C4C,具体教程请参考:http://www.plantcode.cn/chapter/2071...

    2024/4/23 15:34:19
  5. 存储过程 (学习笔记)

    一、什么是存储过程?用什么来调用? 存储过程(stored procedure)是一组为了完成特定功能的SQL语句集合,经编译后存储在服务器端的数据库中,利用存储过程可以加速SQL语句的执行。 自定义存储过程,由用户创建并能完成某一特定功能的存储过程,存储过程既可以有参数又有返回值…...

    2024/4/23 15:34:15
  6. kali-2020.1root用户终端颜色修改

    kali-2020.1root用户终端颜色修改 这是root用户和kali用户终端颜色对比,感觉还是kali用户看着舒服分别在kali用户和root用户下输入echo $PS1查看区别所在之处修改(root身份) : 就是把kali用户下的 .bashrc文件复制到 root用户目录下,然后运行一下cp /home/kali/.bashrc #将…...

    2024/4/23 15:34:14
  7. Vue-Admin-Template Tui.Editor HTML错位问题(未解决)

    正常情况如下图:我的编辑器长这样查看代码,应该是te-tab-active的结束标签丢失,然后错误的包裹了te-preview,导致错位。![在这里插入图片描述](https://img-blog.csdnimg.cn/2020052112582317.png 但是,不知道怎么解决。自己npm安装Tui Editor错误,从Vue-Element-Admin直…...

    2024/4/23 15:34:13
  8. Java中的成员内部类的使用规范

    成员内部类的使用规范,自己看书也没看明白啥,一头雾水,自己琢磨出来了,分享给大家,内容都在图中,有不对的及时评论,以免误导他人。...

    2024/4/23 15:34:15
  9. C++面试宝典:线程通信(C++的promise和future)

    线程通信:C++的promise和future 通过使用 std::promise 和 std::future,就有了task的全部控制权。 std::promise 允许设置一个值,一个消息,或者一个异常。 该结果可以延迟由promise提供。 std::future 可以从promise获取值,请求性获取,值可用的话就可获取到了。 等待prom…...

    2024/4/23 15:34:11
  10. vue+nodejs+express解决跨域问题

    vue+nodejs+express解决跨域问题参考文章: (1)vue+nodejs+express解决跨域问题 (2)https://www.cnblogs.com/jinbang/p/8660654.html 备忘一下。...

    2024/4/17 2:17:47
  11. Java 线程 UncaughtExceptionHandler 异常处理机制

    先看一个例子: public static void main(String[] args) {try {new Thread(() -> {int i = 1/0;}).start();}catch (Throwable e){System.out.println("error...");}}输出结果: Exception in thread "Thread-0" java.lang.ArithmeticException: / by …...

    2024/4/23 15:34:12
  12. JVM条理混乱?看完这篇你就理清楚了(言简意赅版)

    文章内容概要:文章目录一、什么是JVM二、JDK,JRE,JVM的关系三、JVM结构四、GC垃圾回收机制五、垃圾回收算法六、JVM运行实例 一、什么是JVMJVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个Java实现跨平台的最核心的部分。所有的java程序会首先被编译为.class的类文…...

    2024/4/23 15:34:11
  13. 网络编程---Syn_Flood攻击

    Syn_Flood概述 Syn-Flood攻击是当前网络上最为常见的DDoS攻击,也是最为经典的拒绝服务攻击,它利用了TCP协议实现上的一个缺陷,通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。 这种攻击…...

    2024/4/23 15:34:07
  14. idea开发之设置jdk编译版本

    1.idea的settings、project structure中设置2.在pom.xml文件中引入...

    2024/4/23 15:34:06
  15. spring基于注解的增删改查

    首先新建一个实体类,这里不需要构造方法public class Account {private String username;private int money;public void setUsername(String username){this.username=username;}public void setMoney(int money){this.money=money;}public String getUsername() {return use…...

    2024/4/23 15:34:05
  16. LINUX学习笔记之awk用法

    [awk] 用-F指定多分隔符及正则表达式 命令行选项 -F"[@ t]" 告诉awk @, 空格和Tab都是字段分隔符,例如:awk -F"[@ t]" & 39;{print $2,$3}& 39; test以@,空格,Ta 命令行选项 -F"[@ /t]" 告诉awk @, 空格和Tab都是字段分隔符,例如:…...

    2024/4/23 15:34:07
  17. Windows SDK学习之滚动条

    如何获取客户区的尺寸 滚动条的出现最大限度(没有之一)的提高了用户体验,但首先需要客户区的尺寸。 1.在全屏模式下获得客户区的分辨率 GetSystemMetrics(SM_CXSCREEN);->宽度 GetSystemMetrics(SM_CYSCREEN);->高度 2.GetClientRect获取当前窗口尺寸 3.当窗口改变时,…...

    2024/4/23 15:34:04
  18. 点击跟进记录 查询这个学生的跟进信息出现的错误Parameter netStuId not found. Available parameters are [ arg0,param1]

    error: “Internal Server Error” “内部服务器错误” message: “nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘netStuId’ not found. Available parameters are [arg0, netFollow, param1, param2]” 嵌套异常为org.apache.ibati.binding…...

    2024/4/23 15:34:05
  19. 利用C#进行AutoCAD .NET 二次开发 cad官方学习链接

    利用C# 进行cad2018的二次开发需要安装cad2018 vs2015 社区版即可cad2018的二次开发类库:Autodesk_ObjectARX_2018_Win_64_and_32_Bit.sfx项目创建模板:AutoCAD .NET Wizards2018 (非必须,但是安装后比较方法创建,是个项目创建模板)cad官方学习链接:帮助文档https://www.…...

    2024/4/23 15:34:04
  20. 让Hinton后悔投少了的AI公司:吴恩达弟子创办,李飞飞也是投资人

    郭一璞 发自 凹非寺 量子位 报道 | 公众号 QbitAI后悔了后悔了后悔了。位于伯克利的机器人创业公司CovariantAI,B轮4000万美元融资甫一公布,深度学习之父Geoffrey Hinton就后悔了:投少了,应该再多投100倍的。当我的朋友,Radical Ventures的Jordan Jacobs问我如何看待Covar…...

    2024/4/17 2:18:59

最新文章

  1. 源码篇--Nacos服务--中章(5):Nacos客户端启动-实例注册-grpc连接建立

    文章目录 前言一、 前奏&#xff1a;二、客户端连接的建立&#xff1a;2.1 NacosNamingService 创建&#xff1a;2.2 NacosNamingService 初始化&#xff1a;2.3 NamingClientProxyDelegate 长连接建立&#xff1a;2.3.1 grpc 代理对象创建&#xff1a;2.3.2 NamingGrpcClientP…...

    2024/4/24 12:27:44
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 华为2024年校招实习硬件-结构工程师机试题(四套)

    华为2024年校招&实习硬件-结构工程师机试题&#xff08;四套&#xff09; &#xff08;共四套&#xff09;获取&#xff08;WX: didadidadidida313&#xff0c;加我备注&#xff1a;CSDN 华为硬件结构题目&#xff0c;谢绝白嫖哈&#xff09; 结构设计工程师&#xff0c;结…...

    2024/4/18 6:23:51
  4. 蓝桥杯第十五届抱佛脚(十)贪心算法

    蓝桥杯第十五届抱佛脚&#xff08;十&#xff09;贪心算法 贪心算法基本概念 贪心算法是一种在算法设计中常用的方法&#xff0c;它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是最好或最优的算法。 贪…...

    2024/4/19 0:49:59
  5. 文心一言 vs GPT-4 —— 全面横向比较

    对于文心一言和 GPT-4 这两者之间的全面横向比较&#xff0c;我们可以从多个方面来看待它们的区别和优劣势。 文心一言 文心一言是一款基于深度学习的中文文本生成模型&#xff0c;专注于生成优美的古风诗句和语录。以下是它的一些特点&#xff1a; 专注于古风诗句和语录: 文…...

    2024/4/21 15:36:10
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/23 20:58:27
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/23 13:30:22
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/23 13:28:06
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/20 23:26:47
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/23 13:27:44
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/19 11:57:53
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/23 13:29:53
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/23 13:27:22
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/23 13:28:42
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/23 22:01:21
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/23 13:29:23
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/23 13:27:46
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/23 13:47:22
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/19 11:59:23
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/19 11:59:44
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/23 13:28:08
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/23 13:29:47
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/23 13:28:14
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/23 13:27:51
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/23 13:27:19
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57