代理模式之jdk动态代理

对代理模式还不懂的朋友可以先看看这篇静态代理模式:静态代理模式
动态代理是指动态的生成 代理类 真实对象和接口是已经存在了的
1、动态代理和静态代理的角色是一样的;
2、动态代理的代理类是动态生成的;
动态代理分为两类,一类是基于几口的动态代理,一个是基于类的动态代理
a) 基于接口的动态代理-----jdk动态代理
b) 基于类的动态代理----cglib
4、jdk动态代理
关键的两个类: proxy类 和 invocationHandler接口
invocationHandler 是代理实例的 调用处理程序 实现的接口,
有一个方法是invoke (object proxy , Method method object [ ] args )
该方法 在代理实例上 处理方法调用 并返回结果;
proxy -- 被代理的对象;
method -- 对应的是代理实例调用的接口方法的Method实例;(被代理的方法)
args -- 方法调用所需要的参数数组
proxy 提供用于创建动态代理类和实例的静态方法
//伪代码
其中有个重要的方法 newProxyInstance(类加载器, 代理类要实现的接口,invocationHandler)
代码示例:
//出租的抽象接口
public interface Rent {
	void Rent();
}
//被代理的角色
public class Host implements Rent{
	@Override
	public void Rent() {
		System.out.println("房东要租房");
	}
}
//代理类
public class ProxyInvocationHandler implements InvocationHandler {
		private Object target;
		public void setTarget(Object target) {
			this.target = target;
		}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		seeHouse();
		Object result = method.invoke(target, args);
		fare();
		return result;	
	}
	public Object getProxy(){
		/**
		 * 利用jdk的Proxy这个类来为我们动态的生成代理类
		 * this.getClass().getClassLoader(),  通过这个本身这个类的类加载器来加载新的代理类
		 * target.getClass().getInterfaces(), 得到抽象类的接口
		 * this  需要的是InvocationHandler  而proxy这个类实现了InvocationHandler
		 */
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);	
	}
	public void seeHouse(){
		System.out.println("中介带房东看房");
	}
	public void fare(){
		System.out.println("中介收取一波中介费");
	}
}
//测试类
public class Test {
	public static void main(String[] args) {
			Host host = new Host();
			ProxyInvocationHandler ih = new ProxyInvocationHandler(); 
			ih.setTarget(host);
			Rent r = (Rent)ih.getProxy();
			r.Rent();
	}
}
代码输出结果:
中介带房东看房
房东要租房
中介收取一波中介费
项目中稍作改进:
我们增加UserService和UserServiceImpl实现类;
在ProxyInvocationHandler中 我们模拟增加打印日志的功能,增加log();
public class ProxyInvocationHandler implements InvocationHandler {
		private Object target;
		public void setTarget(Object target) {
			this.target = target;
		}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		seeHouse();
		Object result = method.invoke(target, args);
		log(method.getName());
		fare();
		return result;
	}
	public Object getProxy(){
		/**
		 * 利用jdk的Proxy这个类来为我们动态的生成代理类
		 * this.getClass().getClassLoader(),  通过这个本身这个类的类加载器来加载新的代理类
		 * this.getClass().getInterfaces(),   得到实现
		 * this  需要的是InvocationHandler  而proxy这个类实现了InvocationHandler
		 */
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
		
	}
	public void log(String  MethodName){
		System.out.println("执行了:"+MethodName+"方法");
	}
	public void seeHouse(){
		System.out.println("中介带房东看房");
	}
	public void fare(){
		System.out.println("中介收取一波中介费");
	}
}
测试类改为:
public class Test {
	public static void main(String[] args) {
			UserService user = new UserServiceImpl();
			ProxyInvocationHandler ih = new ProxyInvocationHandler(); 
			ih.setTarget(user);
			UserService r = (UserService)ih.getProxy();
			r.add();
	}
}
输出结果为:
中介带房东看房
增加一名新用户
执行了:add方法
中介收取一波中介费

可以看到 打印了 执行了:add方法 这就是我们常用的SpringAOP来做日志管理的原理;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值