Home > Java > javaTutorial > body text

What are the two ways of dynamic proxy?

青灯夜游
Release: 2022-01-06 17:32:05
Original
19208 people have browsed it

Two methods are: 1. JDK dynamic proxy, using the reflection mechanism to generate an anonymous class that implements the proxy interface, and calling InvokeHandler before calling specific methods; 2. CGLIB dynamic proxy, using the asm open source package, Load the class file of the proxy object class and process it by modifying its bytecode to generate a subclass.

What are the two ways of dynamic proxy?

The operating environment of this tutorial: windows7 system, java8 version, DELL G3 computer.

Dynamic proxy is a very important application scenario of reflection. Dynamic proxies are often used in some Java frameworks. For example, Spring's AOP and Dubbo's SPI interface are implemented based on Java dynamic proxy.

There are two methods of dynamic proxy:

  • JDK dynamic proxy: using the reflection mechanism to generate an implementation proxy interface For anonymous classes, call InvokeHandler before calling specific methods.

  • CGLIB dynamic proxy: Use the ASM (open source Java bytecode editing library, operating bytecode) open source package to load the class file of the proxy object class, and modify its characters Section code generates subclasses to handle.

Difference: JDK agent can only generate agents for classes that implement interfaces; CGlib implements agents for classes, generates a subclass for the specified class, and overrides it The method, which is implemented through inherited classes, cannot proxy the final-modified class.

Forcing to use CGlib

<!-- proxy-target-class="false"默认使用JDK动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<aop-config proxy-target-class="true">
<!-- 切面详细配置 -->
</aop-config>
Copy after login

Specific code example:

/**
 * 目标接口类
 */
public interface UserManager {    
    public void addUser(String id, String password);    
    public void delUser(String id);    
}
Copy after login
/**
 * 接口实现类
 */
public class UserManagerImpl implements UserManager {    
    
    @Override
    public void addUser(String id, String password) {    
        System.out.println("调用了UserManagerImpl.addUser()方法!");
    }    
    
    @Override
    public void delUser(String id) {    
        System.out.println("调用了UserManagerImpl.delUser()方法!");
    }    
}
Copy after login
/**
 * JDK动态代理类
 */
public class JDKProxy implements InvocationHandler {    
    
    // 需要代理的目标对象
    private Object targetObject;    
    
    public Object newProxy(Object targetObject) {
        // 将目标对象传入进行代理    
        this.targetObject = targetObject;
        // 返回代理对象 
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }    
    
    // invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 进行逻辑处理的函数
        checkPopedom();
        Object ret = null;
        // 调用invoke方法
        ret = method.invoke(targetObject, args);
        return ret;
    }    
    
    private void checkPopedom() {
        // 模拟检查权限   
        System.out.println("检查权限:checkPopedom()!");    
    }    
}
Copy after login
/**
 * CGlib动态代理类
 */
 public class CGLibProxy implements MethodInterceptor {    
    
    // CGlib需要代理的目标对象
    private Object targetObject;
    
    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        Object proxyObj = enhancer.create();
        return proxyObj;
    }
    
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        // 过滤方法
        if ("addUser".equals(method.getName())) {
            // 检查权限
            checkPopedom();
        }
        obj = method.invoke(targetObject, args);
        return obj;
    }    
    
    private void checkPopedom() {
        System.out.println("检查权限:checkPopedom()!");
    }
}
Copy after login
/**
 * 测试类
 */
public class ProxyTest {
    
    public static void main(String[] args) {
        UserManager userManager = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());
        System.out.println("CGLibProxy:");
        userManager.addUser("tom", "root");
        System.out.println("JDKProxy:");
        JDKProxy jdkProxy = new JDKProxy();
        UserManager userManagerJDK = (UserManager)jdkProxy.newProxy(new UserManagerImpl());
        userManagerJDK.addUser("tom", "root");
    }
}
Copy after login
// 运行结果
CGLibProxy:
检查权限checkPopedom()!
调用了UserManagerImpl.addUser()方法!
JDKProxy:
检查权限checkPopedom()!
掉用了UserManagerImpl.addUser()方法!
Copy after login

Summary:

1. The JDK agent uses the reflection mechanism To implement aop's dynamic proxy, the CGLIB proxy uses the bytecode processing framework asm to generate subclasses by modifying the bytecode. Therefore, the jdk dynamic proxy method has higher efficiency in creating proxy objects but lower execution efficiency. cglib has lower creation efficiency and higher execution efficiency.

2. JDK dynamic proxy mechanism is a delegation mechanism. Specifically, dynamic implementation of interface classes , entrust handler to call the original implementation class method in the dynamically generated implementation class. CGLIB uses the inheritance mechanism. Specifically, the proxy class and the proxy class are inheritance relationships, so the proxy class can be assigned to the proxy class. If it is The proxy class has an interface, so the proxy class can also be assigned to the interface.

(Recommended tutorial: java introductory tutorial)

The above is the detailed content of What are the two ways of dynamic proxy?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template