spring中的动态代理

两种代理原理

jdk动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

spring对代理的选择

  1. 如果目标类实现了接口,默认情况下会采用JDK的动态代理实现AOP
  2. 如果目标类实现了接口,可以强制使用CGLIB实现AOP
  3. 如果目标类没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

JDK动态代理和CGLIB字节码生成的区别?

  1. JDK动态代理需要目标类实现接口
  2. CGLIB是针对类实现代理,主要是对指定的类生成子类,覆盖其中的方法 因为是继承,所以该类或方法最好不要声明成final
  3. CGLIB性能更好

JDK动态代理实现

定义目标类的接口

1
2
3
public interface business {
    void execute();
}

目标类实现接口

1
2
3
4
5
public  class businessIml implements business {
    public void execute() {
        System.out.println("业务处理");
    }
}

代理类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class businessInvacationHandler implements InvocationHandler {
    private Object target;

    //proxy指代理的对象,method指代理对象的某个方法,args指该方法接受的参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("业务处理前");
        Object result = method.invoke(target, args);
        System.out.println("业务处理后");
        return result;
    }

    /*  loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
        interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
        如果我提供了一组接口给它,
        那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
        h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上*/
    public Object getProxy(Object object) {
        this.target=object;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
}
1
2
3
4
5
public static void main(String[] args) {
        businessIml businessIml = new businessIml();
        business proxy = (business)new businessInvacationHandler().getProxy(businessIml);
        proxy.execute();
    }

CGLIB 代理实现

引入依赖

1
2
3
4
5
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>

代理类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class BusinessProxy implements MethodInterceptor {
    
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("业务处理前");
        Object result = methodProxy.invokeSuper(o, args);
        System.out.println("业务处理后");
        return result;
    }

    public Object getProxy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();//用于创建子类
        enhancer.setSuperclass(clazz);//设置父类
        enhancer.setCallback(this);//回调方法的参数为代理类对象BusinessProxy
        // ,最后增强目标类调用的是代理类对象BusinessProxy中的intercept方法
        return enhancer.create();
    }

}
1
2
3
4
5
public static void main(String[] args) {
        businessIml proxy = (businessIml) new BusinessProxy().
        												getProxy(businessIml.class);
        proxy.execute();
    }
Built with Hugo
主题 StackJimmy 设计