国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【動(dòng)態(tài)代理】JDK動(dòng)態(tài)代理與cglib動(dòng)態(tài)代理源碼解析

這篇具有很好參考價(jià)值的文章主要介紹了【動(dòng)態(tài)代理】JDK動(dòng)態(tài)代理與cglib動(dòng)態(tài)代理源碼解析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

JDK動(dòng)態(tài)代理

demo展示

UserService,接口類

public interface UserService {
    void addUser();
}

UserServiceImpl,實(shí)現(xiàn)類

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("register algo");
    }
}

使用代理,測(cè)試效果。

public class JdkTest {

    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxyInstance = (UserService) Proxy.newProxyInstance(JdkTest.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("代理前... ");
                Object invoke = method.invoke(userService, args);
                System.out.println("代理后... ");
                return invoke;
            }
        });
        proxyInstance.addUser();
    }
}

控制臺(tái)輸出:

代理前... 
register algo
代理后... 

源碼分析

Proxy#newProxyInstance,生成代理類的實(shí)例。

  • 核心在于getProxyClass0,生成代理類的類信息
  • 使用自定義的InvocationHandler作為參數(shù),調(diào)用構(gòu)造函數(shù)獲取代理類對(duì)象實(shí)例
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }


    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        return proxyClassCache.get(loader, interfaces);
    }

WeakCache#get

    public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);

        expungeStaleEntries();

        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)

            // lazily construct a Factory
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

ProxyClassFactory#apply,實(shí)現(xiàn)了代理類的創(chuàng)建。

  • 生成代理類字節(jié)碼文件。
  • 加載字節(jié)碼,生成指定代理對(duì)象。
        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }

            String proxyPkg = null;     // package to define proxy class in
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            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)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }

            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class.
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }

ProxyGenerator#generateProxyClass(),生成類信息文件。將要生成代理類的字節(jié)碼文件保存在磁盤(pán)中

    public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        final byte[] var4 = var3.generateClassFile();
        if (saveGeneratedFiles) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if (var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                            Files.createDirectories(var3);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class");
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }

        return var4;
    }

ProxyGenerator#generateClassFile,添加代理的hashCode、equals、toString方法。開(kāi)始寫(xiě)class字節(jié)碼文件

    private byte[] generateClassFile() {
        this.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) {
            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);
            }
        }

        Iterator var11 = this.proxyMethods.values().iterator();

        List var12;
        while(var11.hasNext()) {
            var12 = (List)var11.next();
            checkReturnTypes(var12);
        }
    }

cglib動(dòng)態(tài)代理

demo展示

攔截器

public class CglibMethodInterceptor implements MethodInterceptor {
    private Object target;

    public CglibMethodInterceptor(Object target) {
        this.target = target;
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib before do ....");

        Object result = method.invoke(target, objects);

        System.out.println("cglib after do ......");

        return result;
    }
}

測(cè)試效果

public class CglibTest {

    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        CglibMethodInterceptor invocationHandler = new CglibMethodInterceptor(helloWorld);

        Enhancer enhancer = new Enhancer();
        //設(shè)置代理什么類
        enhancer.setSuperclass(helloWorld.getClass());
        //設(shè)置invoker
        enhancer.setCallback(invocationHandler);

        HelloWorld result = (HelloWorld) enhancer.create();

        result.sayHello();
    }
}

控制臺(tái)輸出

代理前... 
register algo
代理后... 

源碼解析

Enhancer#create(),創(chuàng)建EnhancerKey對(duì)象。

	public Object create() {
		classOnly = false;
		argumentTypes = null;
		return createHelper();
	}

	private Object createHelper() {
		preValidate();
		Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
				ReflectUtils.getNames(interfaces),
				filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
				callbackTypes,
				useFactory,
				interceptDuringConstruction,
				serialVersionUID);
		this.currentKey = key;
		Object result = super.create(key);
		return result;
	}

AbstractClassGenerator#create,調(diào)用ClassLoaderData的get方法。

	protected Object create(Object key) {
		try {
			ClassLoader loader = getClassLoader();
			Map<ClassLoader, ClassLoaderData> cache = CACHE;
			ClassLoaderData data = cache.get(loader);
			if (data == null) {
				synchronized (AbstractClassGenerator.class) {
					cache = CACHE;
					data = cache.get(loader);
					if (data == null) {
						Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
						data = new ClassLoaderData(loader);
						newCache.put(loader, data);
						CACHE = newCache;
					}
				}
			}
			this.key = key;
			Object obj = data.get(this, getUseCache());
			if (obj instanceof Class) {
				return firstInstance((Class) obj);
			}
			return nextInstance(obj);
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
	}

ClassLoaderData封裝了load方法,當(dāng)獲取緩存獲取不到,調(diào)用gen.generate(ClassLoaderData.this);。

		public ClassLoaderData(ClassLoader classLoader) {
			if (classLoader == null) {
				throw new IllegalArgumentException("classLoader == null is not yet supported");
			}
			this.classLoader = new WeakReference<ClassLoader>(classLoader);
			Function<AbstractClassGenerator, Object> load =
					new Function<AbstractClassGenerator, Object>() {
						public Object apply(AbstractClassGenerator gen) {
							Class klass = gen.generate(ClassLoaderData.this);
							return gen.wrapCachedClass(klass);
						}
					};
			generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
		}

AbstractClassGenerator#generate,生成字節(jié)碼。

	protected Class generate(ClassLoaderData data) {
		Class gen;
		Object save = CURRENT.get();
		CURRENT.set(this);
		try {
			ClassLoader classLoader = data.getClassLoader();
			if (classLoader == null) {
				throw new IllegalStateException("ClassLoader is null while trying to define class " +
						getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
						"Please file an issue at cglib's issue tracker.");
			}
			synchronized (classLoader) {
				String name = generateClassName(data.getUniqueNamePredicate());
				data.reserveName(name);
				this.setClassName(name);
			}
			if (attemptLoad) {
				try {
					gen = classLoader.loadClass(getClassName());
					return gen;
				}
				catch (ClassNotFoundException e) {
					// ignore
				}
			}
			byte[] b = strategy.generate(this);
			String className = ClassNameReader.getClassName(new ClassReader(b));
			ProtectionDomain protectionDomain = getProtectionDomain();
			synchronized (classLoader) { // just in case
				// SPRING PATCH BEGIN
				gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
				// SPRING PATCH END
			}
			return gen;
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
		finally {
			CURRENT.set(save);
		}
	}

KeyFactory.Generator#generateClass,通過(guò)asm生成了Enhancer.EnhancerKey的代理類。

		public void generateClass(ClassVisitor v) {
			ClassEmitter ce = new ClassEmitter(v);

			Method newInstance = ReflectUtils.findNewInstance(keyInterface);
			if (!newInstance.getReturnType().equals(Object.class)) {
				throw new IllegalArgumentException("newInstance method must return Object");
			}

			Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
			ce.begin_class(Constants.V1_8,
					Constants.ACC_PUBLIC,
					getClassName(),
					KEY_FACTORY,
					new Type[]{Type.getType(keyInterface)},
					Constants.SOURCE_FILE);
			EmitUtils.null_constructor(ce);
			EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));

			int seed = 0;
			CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
					TypeUtils.parseConstructor(parameterTypes),
					null);
			e.load_this();
			e.super_invoke_constructor();
			e.load_this();
			List<FieldTypeCustomizer> fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class);
			for (int i = 0; i < parameterTypes.length; i++) {
				Type parameterType = parameterTypes[i];
				Type fieldType = parameterType;
				for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
					fieldType = customizer.getOutType(i, fieldType);
				}
				seed += fieldType.hashCode();
				ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
						getFieldName(i),
						fieldType,
						null);
				e.dup();
				e.load_arg(i);
				for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
					customizer.customize(e, i, parameterType);
				}
				e.putfield(getFieldName(i));
			}
			e.return_value();
			e.end_method();

			// hash code
			e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
			int hc = (constant != 0) ? constant : PRIMES[(Math.abs(seed) % PRIMES.length)];
			int hm = (multiplier != 0) ? multiplier : PRIMES[(Math.abs(seed * 13) % PRIMES.length)];
			e.push(hc);
			for (int i = 0; i < parameterTypes.length; i++) {
				e.load_this();
				e.getfield(getFieldName(i));
				EmitUtils.hash_code(e, parameterTypes[i], hm, customizers);
			}
			e.return_value();
			e.end_method();

			// equals
			e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
			Label fail = e.make_label();
			e.load_arg(0);
			e.instance_of_this();
			e.if_jump(CodeEmitter.EQ, fail);
			for (int i = 0; i < parameterTypes.length; i++) {
				e.load_this();
				e.getfield(getFieldName(i));
				e.load_arg(0);
				e.checkcast_this();
				e.getfield(getFieldName(i));
				EmitUtils.not_equals(e, parameterTypes[i], fail, customizers);
			}
			e.push(1);
			e.return_value();
			e.mark(fail);
			e.push(0);
			e.return_value();
			e.end_method();

			// toString
			e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
			e.new_instance(Constants.TYPE_STRING_BUFFER);
			e.dup();
			e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
			for (int i = 0; i < parameterTypes.length; i++) {
				if (i > 0) {
					e.push(", ");
					e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
				}
				e.load_this();
				e.getfield(getFieldName(i));
				EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizers);
			}
			e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
			e.return_value();
			e.end_method();

			ce.end_class();
		}

Enhancer#generate,調(diào)用父類的方法生成。

	@Override
	protected Class generate(ClassLoaderData data) {
		validate();
		if (superclass != null) {
			setNamePrefix(superclass.getName());
		}
		else if (interfaces != null) {
			setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
		}
		return super.generate(data);
	}

AbstractClassGenerator#generate,執(zhí)行生成策略。

	protected Class generate(ClassLoaderData data) {
		Class gen;
		Object save = CURRENT.get();
		CURRENT.set(this);
		try {
			ClassLoader classLoader = data.getClassLoader();
			if (classLoader == null) {
				throw new IllegalStateException("ClassLoader is null while trying to define class " +
						getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
						"Please file an issue at cglib's issue tracker.");
			}
			synchronized (classLoader) {
				String name = generateClassName(data.getUniqueNamePredicate());
				data.reserveName(name);
				this.setClassName(name);
			}
			if (attemptLoad) {
				try {
					gen = classLoader.loadClass(getClassName());
					return gen;
				}
				catch (ClassNotFoundException e) {
					// ignore
				}
			}
			byte[] b = strategy.generate(this);
			String className = ClassNameReader.getClassName(new ClassReader(b));
			ProtectionDomain protectionDomain = getProtectionDomain();
			synchronized (classLoader) { // just in case
				// SPRING PATCH BEGIN
				gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
				// SPRING PATCH END
			}
			return gen;
		}
		catch (RuntimeException | Error ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new CodeGenerationException(ex);
		}
		finally {
			CURRENT.set(save);
		}
	}

Enhancer#generateClass生成代理類的信息。

Cglib和jdk動(dòng)態(tài)代理的區(qū)別?

1、Jdk動(dòng)態(tài)代理:利用攔截器(必須實(shí)現(xiàn)InvocationHandler)加上反射機(jī)制生成一個(gè)代理接口的匿名類,在調(diào)用具體方法前調(diào)用InvokeHandler來(lái)處理

2、 Cglib動(dòng)態(tài)代理:利用ASM框架,對(duì)代理對(duì)象類生成的class文件加載進(jìn)來(lái),通過(guò)修改其字節(jié)碼生成子類來(lái)處理。

【動(dòng)態(tài)代理】JDK動(dòng)態(tài)代理與cglib動(dòng)態(tài)代理源碼解析文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-443456.html

到了這里,關(guān)于【動(dòng)態(tài)代理】JDK動(dòng)態(tài)代理與cglib動(dòng)態(tài)代理源碼解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 通俗易懂 快速理解 JDK動(dòng)態(tài)代理 和 cglib動(dòng)態(tài)代理

    通俗易懂 快速理解 JDK動(dòng)態(tài)代理 和 cglib動(dòng)態(tài)代理

    動(dòng)態(tài)代理的實(shí)現(xiàn)方案有兩種, JDK動(dòng)態(tài)代理 和 CGLIB動(dòng)態(tài)代理 ,區(qū)別在于JDK自帶的動(dòng)態(tài)代理,必須要有接口,而CGLIB動(dòng)態(tài)代理有沒(méi)有接口都可以。 JDK動(dòng)態(tài)代理 :JDK原生的實(shí)現(xiàn)方式,需要被代理的目標(biāo)類必須實(shí)現(xiàn)接口。因?yàn)檫@個(gè)技術(shù)要求 代理對(duì)象和目標(biāo)對(duì)象實(shí)現(xiàn)同樣的接口 (兄

    2024年02月08日
    瀏覽(23)
  • 【spring】jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理的區(qū)別

    一、說(shuō)明 1.spring aop中的動(dòng)態(tài)代理主要有兩種方式,jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理 2.從實(shí)現(xiàn)接口、繼承父類的角度討論區(qū)別 3.從限制角度討論區(qū)別 4.從性能上討論區(qū)別 二、區(qū)別 1.jdk動(dòng)態(tài)代理只提供接口類的代理,如果目標(biāo)類不是接口,只能用cglib代理 2.jdk動(dòng)態(tài)代理會(huì)在運(yùn)行時(shí)為目

    2024年02月16日
    瀏覽(19)
  • java中的靜態(tài)代理、jdk動(dòng)態(tài)代理以及CGLIB 動(dòng)態(tài)代理

    代理模式是一種比較好理解的設(shè)計(jì)模式。簡(jiǎn)單來(lái)說(shuō)就是 我們使用代理對(duì)象來(lái)代替對(duì)真實(shí)對(duì)象(real object)的訪問(wèn),這樣就可以在不修改原目標(biāo)對(duì)象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對(duì)象的功能 那以下文章主要談三種代理模式, 分別是靜態(tài)代理,jdk的動(dòng)態(tài)代理,cglib的動(dòng)

    2024年02月11日
    瀏覽(26)
  • SpringAOP-說(shuō)說(shuō) JDK動(dòng)態(tài)代理和 CGLIB 代理

    SpringAOP-說(shuō)說(shuō) JDK動(dòng)態(tài)代理和 CGLIB 代理

    Spring 的 AOP 是通過(guò)動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)的,動(dòng)態(tài)代理主要有兩種方式 JDK 動(dòng)態(tài)代理和 Cglib 動(dòng)態(tài)代理,這兩種動(dòng)態(tài)代理的使用和原理有些不同。 JDK 動(dòng)態(tài)代理 Interface :JDK動(dòng)態(tài)代理是基于接口的代理,它要求目標(biāo)類實(shí)現(xiàn)一個(gè)接口。 InvocationHandler :InvocationHandler 是一個(gè)接口,可以通過(guò)

    2024年01月18日
    瀏覽(25)
  • 3_代理模式(動(dòng)態(tài)代理JDK原生和CGLib)

    1.概念 代理模式(Proxy Pattern )是指 為其他對(duì)象提供一種代理,以控制對(duì)這個(gè)對(duì)象的訪問(wèn) ,屬于結(jié)構(gòu)型模式。 在某些情況下,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用。 使用代理模式主要有兩個(gè)目的: 一是保護(hù)目標(biāo)

    2024年01月17日
    瀏覽(21)
  • AOP、AspectJ、JDK動(dòng)態(tài)代理、CGLIB

    AOP(Aspect Orient Programming),作為面向?qū)ο缶幊痰囊环N補(bǔ)充,廣泛應(yīng)用于處理一些具有橫切性質(zhì)的系統(tǒng)級(jí)服務(wù),如事務(wù)管理、安全檢查、緩存、日志記錄管理等。 AOP 實(shí)現(xiàn)的關(guān)鍵就在于 AOP 框架自動(dòng)創(chuàng)建的 AOP 代理,AOP 代理則可分為靜態(tài)代理和動(dòng)態(tài)代理兩大類。 其中靜態(tài)代理是

    2024年02月11日
    瀏覽(53)
  • Spring Boot 中的 AOP,到底是 JDK 動(dòng)態(tài)代理還是 Cglib 動(dòng)態(tài)代理

    Spring Boot 中的 AOP,到底是 JDK 動(dòng)態(tài)代理還是 Cglib 動(dòng)態(tài)代理

    大家都知道,AOP 底層是動(dòng)態(tài)代理,而 Java 中的動(dòng)態(tài)代理有兩種實(shí)現(xiàn)方式: 基于 JDK 的動(dòng)態(tài)代理 基于 Cglib 的動(dòng)態(tài)代理 這兩者最大的區(qū)別在于基于 JDK 的動(dòng)態(tài)代理需要被代理的對(duì)象有接口,而基于 Cglib 的動(dòng)態(tài)代理并不需要被代理對(duì)象有接口。 那么,Spring 中的 AOP 是怎么實(shí)現(xiàn)的

    2024年02月12日
    瀏覽(24)
  • Spring之CGLIB和JDK動(dòng)態(tài)代理底層實(shí)現(xiàn)

    Spring之CGLIB和JDK動(dòng)態(tài)代理底層實(shí)現(xiàn)

    目錄 CGLIB 使用示例-支持創(chuàng)建代理對(duì)象,執(zhí)行代理邏輯 使用示例-多個(gè)方法,走不同的代理邏輯 JDK動(dòng)態(tài)代理 使用示例-支持創(chuàng)建代理對(duì)象,執(zhí)行代理邏輯 ProxyFactory 如何自動(dòng)在CGLIB和JDK動(dòng)態(tài)代理轉(zhuǎn)換 使用示例-使用CGLIB代理方式 使用示例-使用JDK動(dòng)態(tài)代理方式 Spring會(huì)自動(dòng)在JDK動(dòng)態(tài)

    2024年04月25日
    瀏覽(29)
  • springAop使用的動(dòng)態(tài)代理是jdk還是cglib

    Spring AOP使用的動(dòng)態(tài)代理可以是JDK動(dòng)態(tài)代理或CGLIB動(dòng)態(tài)代理,具體選擇哪種代理方式取決于被代理的目標(biāo)對(duì)象的類型和配置。 當(dāng)被代理的目標(biāo)對(duì)象實(shí)現(xiàn)了至少一個(gè)接口時(shí),Spring AOP會(huì)默認(rèn)使用JDK動(dòng)態(tài)代理。JDK動(dòng)態(tài)代理基于接口生成代理類,通過(guò)反射機(jī)制調(diào)用目標(biāo)對(duì)象的方法。 而

    2024年02月09日
    瀏覽(21)
  • 靜態(tài)代理、jdk、cglib動(dòng)態(tài)代理 搞不清? 看這個(gè)文章就懂了

    靜態(tài)代理、jdk、cglib動(dòng)態(tài)代理 搞不清? 看這個(gè)文章就懂了

    代理模式是一種比較好的理解的設(shè)計(jì)模式。簡(jiǎn)單來(lái)說(shuō)就是 : 我們使用代理對(duì)象來(lái)增強(qiáng)目標(biāo)對(duì)象(target obiect),這樣就可以在不修改原目標(biāo)對(duì)象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對(duì)象的功能。 將核心業(yè)務(wù)代碼和非核心的公共代碼分離解耦,提高代碼可維護(hù)性,讓被代理

    2024年02月14日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包