Java 设计模式之代理模式

介绍

代理模式是Java常见的设计模式之一,代理模式是指客户端不直接调用实际的对象,而是通过调用代理对象,间接调用实际对象,简单来说就是不改变源码的情况下,实现对实际对象的功能扩展。
一般客户端不想直接访问实际对象或访问实际对象存在困难,通过一个代理对象来完成间接访问。

代理模式的实现

代理模式可以有两种实现方式,我们根据加载被代理类的时机不同,将代理分为静态代理和动态代理。如果我们在代码编译时就确定了被代理的类是哪一个,那么就可以直接使用静态代理;如果不能确定,那么可以使用类的动态加载机制,在代码运行期间加载被代理的类这就是动态代理,比如RPC框架和Spring AOP机制。

静态代理

代理类接受一个接口的对象,任何实现该接口的对象都可以通过代理类进行代理,增加了通用性,如:
Subject 接口

public interface Subject {
    void visit();
}

实现了Subject接口的两个类

目标对象
public class RealSubject implements Subject {

    private String name = "yk";
    @Override
    public void visit() {
        System.out.println(name);
    }
}
代理对象
public class ProxySubject implements Subject{

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void visit() {
        subject.visit();
    }
}

具体调用如下

public class Client {

    public static void main(String[] args) {
        ProxySubject subject = new ProxySubject(new RealSubject());
        subject.visit();
    }
}

静态代理也有缺点,每一个代理对象都必须实现一遍目标对象的接口,如果接口增加方法,则代理类必须跟着修改,其次代理类每一个接口对应一个目标对象,如果目标对象很多,则静态代理类就非常臃肿。

动态代理

动态代理区别于静态代理是根据代理的对象,动态创建代理类,这样避免静态代理中代理类接口过多的问题,动态代理实现的方式是通过反射来实现的,有两种=方式来时先动态代理:

JDK代理

JDK代理要实现java反射包下的一个接口InvocationHandler

package java.lang.reflect;
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
	throws Throwable;
}

InvocationHandler接口中只有一个invoke方法我们通过代理类调用目标对象方法时,最终都会委托给这个invoke方法执行,所以我们就可以在这个invoke方法中对被代理类进行增强或做一些其他操作。

public class MyInvocationHandler implements InvocationHandler{
	private Object object;
	public MyInvocationHandler(Object object){
		this.object = object;
	}
 
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("MyInvocationHandler invoke begin");
		System.out.println("proxy: "+ proxy.getClass().getName());
		System.out.println("method: "+ method.getName());
		for(Object o : args){
			System.out.println("arg: "+ o);
		}
		//通过反射调用 被代理类的方法
		method.invoke(object, args);
		System.out.println("MyInvocationHandler invoke end");
		return null;
	}

在使用时创建目标对象和代理类对象,然后定义接口应用
jdk的代理让我们在不直接访问某些对象的情况下,通过代理机制也可以访问被代理对象的方法,这种技术可以应用在很多地方比如RPC框架,Spring AOP机制,但是我们看到jdk的代理机制必须要求被代理类实现某个方法,这样在生成代理类的时候才能知道重新那些方法。这样一个没有实现任何接口的类就无法通过jdk的代理机制进行代理,当然解决方法是使用cglib的代理机制进行代理

Cglib代理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值