静态代理与动态代理

首先,我们先讲一下为什么要用代理模式。举个例子,在我们的项目开发中,除了有业务模块,还有公共领域模块,比如权限校验、日志处理等。
如果我们在业务模块中想要实现添加用户的功能,而且还想知道是谁添加了用户,我们该怎么去实现我们的代码呢?直接在service层去修改代码吗?这样会导致公共模块与业务模块掺杂在一起了,如果以后我们不想要这部分公共模块了,我们还需要去业务模块中去修改代码,这不利于程序的升级维护。
那我们应该怎么做呢?这就需要用到代理模式了。
代理分为静态代理与动态代理。
静态代理
我们先来实现一个简单的静态代理,下面的代码是我们的业务模块,称之为真实角色,我们要为其添加一个代理角色。

public class TestService {
	public void addUser() {
		System.out.println("用户添加");
	}

	public void queryUser(String name,String adress) {
		System.out.println("查询用户"+name+"地址"+adress);
		
	}
}

代理角色的代码实现如下,logger方法可以理解为我们的公共模块,在这个类中我们维护了一个真实角色的对象,然后将公共模块添加进代理角色实现的方法中。我们应该保持真实角色与代理角色的方法名一致,这可以通过实现共同的接口来完成。

	/*
	 * 静态代理类
	 */
	private TestService service = new TestService();
	private void logger() {
		System.out.println("某人执行了添加操作");
	}
	
	public void addUser() {
		this.logger();
		this.service.addUser();
	}

	public void queryUser(String name,String adress) {
		// TODO Auto-generated method stub
		this.service.queryUser(adress, adress);
	}

既然静态代理就可以实现我们的功能了,为什么还会用动态代理呢?大家想一下,如果我们的真实角色非常多的话,即业务模块特别多,相应的代理角色也会增多,这使得我们编写代码特别麻烦,所以我们就需要通过动态代理来生成代理角色。
动态代理
动态代理会在运行过程中自动生成一个代理类,而不需要我们手动编写。
动态代理实现方法有两种。一是基于jdk的动态代理,面向接口来实现,二是基于cglib的动态代理,面向抽象类来实现。
实现动态代理需要两个类,Proxy与InvocationHandler。
Proxy提供了创建动态代理类(getProxyClass)和代理对象(newProxyInstance)的静态方法。
我们接下来简单实现一个基于jdk的动态代理。

public class ProxyFactory<T> {
	public T getProxyObj(Object obj) {
		//obj为要实现代理类的真实角色
		Class clazz = obj.getClass();
		ClassLoader loader = clazz.getClassLoader();
		Class[] interfaces = clazz.getInterfaces();
		T proxyObj = (T) Proxy.newProxyInstance(loader, interfaces, getHandler(obj));
		return proxyObj;

	}

	public InvocationHandler getHandler(final Object obj) {

		InvocationHandler handler = new InvocationHandler() {

			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// TODO Auto-generated method stub
				System.out.println("動態代理");
				method.invoke(obj, args);
				return null;
			}
		};

		return handler;

	}

}

CLassLoader指定生成动态代码类的类加载器。
interface用来指定要生成哪个接口的代理类。
InvocationHandler用来控制原始方法的执行,实现对原始方法的增强。
接口中定义的所有方法,一旦执行,就转换成InvocationHandler的invoke方法来执行。
在invoke中通过反射来调用原方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值