动态代理模式:JDK和Cglib的代码实现

JDK和Cglib的代码实现

        • Ⅰ JDK的方式
          • (1)创建接口: IJdkService.java
          • (2)创建接口实现类:JdkServiceImpl.java
          • (3)使用Proxy 类的newProxyInstance方法创建接口代理对象
        • Ⅱ Cglib的方式
          • (1) 创建被代理类:CglibService.java
          • (2) 传入 callback对象,对目标增强:CglibServiceInterceptor.java

JDK的方式:被代理类必须实现接口,基于InvocationHandler、Proxy.newProxyInstance生成代理类。(动态代理)

CGLIB的方式:被代理类不需要实现接口。(动态代理)

Ⅰ JDK的方式

反射包java.lang.reflect有一个Proxy类:Proxy提供了创建动态代理类和实例的静态方法。

public class Proxy extends Object
implements Serializable

调用newProxyInstance 方法:返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

static Object newProxyInstance(ClassLoader loader,<?>[] interfaces, 
								InvocationHandler h) 

方法有三个参数:
第一参数,类加载器
第二参数,增强方法所在的类,这个类实现的接口,可以支持多个接口
第三参数,实现这个接口InvocationHandler,创建代理对象,写增强的部分

(1)创建接口: IJdkService.java
package com.glp.pojo;

public interface IJdkService
{
   public void service();
}
(2)创建接口实现类:JdkServiceImpl.java
package com.glp.pojo;

public class JdkServiceImpl implements IJdkService
{
	@Override
	public void service()
	{
		System.out.println("service...");
	}

}
(3)使用Proxy 类的newProxyInstance方法创建接口代理对象
package com.glp.pojo;

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

//创建代理对象
class JdkServiceProxy implements InvocationHandler{

    private Object obj;
	
	//将代理对象obj,通过构造函数传递进来
    public JdkServiceProxy(Object obj)
    {
        this.obj = obj;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法执行前的逻辑
        System.out.println("方法执行前");
        
        //执行原生类的方法,动态代理的本质就是使用反射!!!
        Object result = method.invoke(obj, args);
        
        //方法执行后的逻辑
        System.out.println("方法执行后");
        return result;
    }
}

public class JDKProxy {
    public static void main(String[] args) {
    	//要被代理的接口
        Class[] interfaces = {IJdkService.class};
        
        //要被代理的对象实现类
        JdkServiceImpl jdkService = new JdkServiceImpl();
        
        IJdkService iJdkService=
        (IJdkService)Proxy.newProxyInstance(
        				JDKProxy.class.getClassLoader(), 
        				interfaces, 
        				new JdkServiceProxy(jdkService));
        				
        iJdkService.service();
    }
}
Ⅱ Cglib的方式
(1) 创建被代理类:CglibService.java
public class CglibService
{
	public void service()
	{
		System.out.println("service start...");
	}
}
(2) 传入 callback对象,对目标增强:CglibServiceInterceptor.java
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

class CglibServiceInterceptor implements MethodInterceptor {
    // 传入被代理的目标对象
    private Object target;

    // 在构造方法中传入被代理的目标对象
    public CglibServiceInterceptor(Object target) {
        this.target = target;
    }
    // 创建代理对象方法
    public Object createProxy() {
        // 1、 创建Enhancer对象
        Enhancer enhancer = new Enhancer();

        // 2、 cglib创建代理,对目标对象,创建子类对象
        enhancer.setSuperclass(target.getClass());

        // 3、传入 callback对象,对目标增强
        enhancer.setCallback(this);

        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("before...");

        //执行原生方法
        Object returnObj = method.invoke(target, objects);

        System.out.println("after...");
        return returnObj;
    }
}

public class CglibInterceptor{
    public static void main(String[] args) {
        CglibService cglibService = new CglibService();

        //调用createProxy方法获取代理对象
        CglibService interceptor = 
        (CglibService)new CglibServiceInterceptor(cglibService)
        .createProxy();
        
        interceptor.service();
    }
}

注意:

  • 使用createProxy()方法,设置 callback 实现增强代码 (类似 JDK代理 中的newProxyInstance方法)。

你可能感兴趣的:(Spring,java,spring)