设计模式-动态代理

什么是代理模式

代理模式又叫委托模式,是为某个对象提供一个代理对象,并且由代理对象控制对原对象的访问。代理模式通俗来讲就是我们生活中常见的中介。

什么是动态代理?

动态代理就是在程序运行期间 通过java的反射机制,创建出代理类对象

动态代理的优点:

在需要代理多个类时,动态代理只需创建一个统一的代理类,而不必像静态代理那样,需要为每个包含业务逻辑的类单独创建代理类。

JDK实现动态代理

使用JDK动态代理步骤

     ①创建被代理的接口和类;
     ②创建InvocationHandler接口的实现类,在invoke方法中实现代理逻辑;
     ③通过Proxy的静态方法newProxyInstance( ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象
     ④使用代理对象。

创建InvocationHandler接口的实现类

package com.demo.design_patterns.proxy;

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


public class TransactionInvocationHandler implements InvocationHandler{
	
	private Object target;
	
	public TransactionInvocationHandler(Object target){
		
		this.target = target;
		
	}
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("执行代理方法前的处理");
		Object invoke = method.invoke(target, args);
		System.out.println("执行代理方法后的处理");
		return invoke;
	}


	/**
	 * Proxy类:核心的对象,创建代理对象。之前创建对象都是 new 类的构造方法()
	 * 现在我们是使用Proxy类的方法,代替new的使用。
	 *
	 * 方法: 静态方法 newProxyInstance()
	 * 作用是: 创建代理对象, 等同于静态代理中的TaoBao taoBao = new TaoBao();
	 * 参数:
	 * ClassLoader loader 类加载器,负责向内存中加载对象的。 使用反射获取对象的ClassLoader
	 * 类a , a.getCalss().getClassLoader(), 目标对象的类加载器
	 * Class<?>[] interfaces: 接口, 目标对象实现的接口,也是反射获取的。
	 * InvocationHandler h : 就是当前的这个类
	 * @return
	 */

	public Object getProxy(){
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
		
	}
	
}

创建一个方便操作的工厂类

package com.demo.design_patterns.proxy;

public interface ProxyFactory {
    public static Object getService(Object service){
        //这里返回的是代理类对象
        return new TransactionInvocationHandler(service).getProxy();
    }
}

执行结果

Cglib动态代理

cglib动态代理和jdk动态代理的区别:  jdk动态代理必须要求被代理类实现了某个接口,而cglib无此要求

代码实现

创建一个类实现了MethodInterceptor接口 

package com.demo.design_patterns.proxy.cglib;

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

import java.lang.reflect.Method;


public class LogInterceptor implements MethodInterceptor {

    /**
     * @param obj         表示要进行增强的对象
     * @param method      表示拦截的方法
     * @param objects     数组表示参数列表,基本数据类型需要传入其包装类型,如int-->Integer、long-Long、double-->Double
     * @param methodProxy 表示对方法的代理,invokeSuper方法表示对被代理对象方法的调用
     * @return 执行结果
     * @throws Throwable 异常
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("登录前的处理");
        // 注意这里是调用invokeSuper而不是invoke,否则死循环;
        // methodProxy.invokeSuper执行的是原始类的方法;
        // method.invoke执行的是子类的方法;
        Object result = methodProxy.invokeSuper(obj, objects);
        System.out.println("登录后的处理");
        return result;
    }

}
package com.demo.design_patterns.proxy.cglib;

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

public class CglibFactory {
    public static <T extends MethodInterceptor> Object get(Class proxy, T interceptor) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(proxy);
        enhancer.setCallback(interceptor);

        return enhancer.create();
    }
}

执行结果 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值