spring aop-proxy articles, java Proxy proxy & cglib proxy

1. Java native agent

1. Introduction to the concept of agency

为某个对象提供一个代理,以控制对这个对象的访问。
代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理
对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行
完请求后的后续处理。

2. Agent classification

Java proxies are divided into two categories, static proxies and dynamic proxies.

The static proxy generates the source code of the proxy class by writing the code, and then compiles the proxy class. The so-called static means that the bytecode file of the proxy class already exists before the program runs, and the relationship between the proxy class and the delegate class is determined before running.

The source code of the dynamic proxy class is dynamically generated by the JVM according to mechanisms such as reflection during the running of the program, so there is no bytecode file of the proxy class. The relationship between the proxy class and the delegate class is determined when the program is running.

3. Dynamic proxy example

Create with java.lang.reflect.Proxy

3.1 Interface part

To create a proxy using Proxy, the interface must be defined in advance

package wang.conge.javasedemo.core.proxy;

public interface HelloService {
    public String sayHello(String name);
}

3.2 Business Implementation Part

package wang.conge.javasedemo.core.proxy;

public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        return "hello:" + name;
    }

}

3.3 Agency business part

package wang.conge.javasedemo.core.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class HelloInvocationHandler implements InvocationHandler{
    private Object delegate; 
    
    public HelloInvocationHandler(Object delegate){
        this.delegate = delegate;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke");
        return method.invoke(this.delegate, args);
    }

}

3.4 Test code

package wang.conge.javasedemo.core.proxy;

import java.lang.reflect.Proxy;

public class JavaProxyTest {
    public static void main(String[] args) {
        HelloInvocationHandler invocationHandler = new HelloInvocationHandler(new HelloServiceImpl());

        HelloService helloService = (HelloService) Proxy.newProxyInstance(HelloService.class.getClassLoader(),
                new Class[] { HelloService.class }, invocationHandler);

        System.out.println(helloService.sayHello("conge"));
    }
}

operation result

invokehello:conge

3.5 Proxy proxy summary

Usage summary:

主要使用java.lang.reflect.Proxy 进行创建代理类
主要方法:public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h);

第一个参数是ClassLoader,也即是加载所要代理类的相应的ClassLoader
第二个参数是interfaces,即是所要代理类的接口
第三个参数是代理业务部分,需要实现InvocationHandler接口
                                          

Summary of advantages and disadvantages:

优点:
1、可以替代java静态代理,集中式处理

缺点:
1、所代理的类,必须预先定义接口,不能直接没有定义接口的类
2、所代理的接口也必须是public类型,如果是package ,必须在访问包的顶层目录

2. Cglib agent

Because Proxy cannot proxy classes that do not define interfaces, the defect is relatively large. But there is another solution to this problem. cglib.

1. Introduction to cglib

cglib简述
           Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理:
使用CGLIB需要导入以下两个jar文件:
    $1:    asm.jar – CGLIB的底层实现
    $2:   cglib.jar – CGLIB的核心jar包。
CGLIB的核心类:
    net.sf.cglib.proxy.Enhancer – 主要的增强类
    net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
    net.sf.cglib.proxy.MethodProxy – JDK的Java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用:
    Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。

2. Proxying with cglib

2.1 Depends on cglib

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

2.2 Business Services

Or use HelloServiceImpl of java native agent, see Native agent 3.2

2.3 Agency business part

package wang.conge.javasedemo.core.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class HelloCglibHandler implements MethodInterceptor {
    private Object delegate; 
    
    public HelloCglibHandler(Object delegate){
        this.delegate = delegate;
    }
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("intercept");
        return method.invoke(delegate, args);
    }

}

2.4 Test code

package wang.conge.javasedemo.core.cglib;

import net.sf.cglib.proxy.Enhancer;
import wang.conge.javasedemo.core.proxy.HelloServiceImpl;

public class EnhancerTest {
    public static void main(String[] args) {
        HelloCglibHandler cglibHandler = new HelloCglibHandler(new     HelloServiceImpl());

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloServiceImpl.class);
        enhancer.setCallback(cglibHandler);
        
        HelloServiceImpl helloService = (HelloServiceImpl) enhancer.create();
        
        System.out.println(helloService.sayHello("conge"));
    }
}

operation result:

intercepthello:conge

2.5 Summary of cglib proxy

 

主要使用Enhancer进行创建代理类,可以直接对类进行代理,运行速度也比原生代理要快。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326170357&siteId=291194637