java代理

25 篇文章 0 订阅
21 篇文章 0 订阅

代理模式定义:为其他对象提供一种代理一控制对这个对象的访问。代理对象起到中介作用,可以去掉功能服务或者增加额外服务。

例如:买火车票,去售票处。

常见几种代理模式:

  1. 远程代理:为不同地理的对象提供局域网代表对象
  2. 虚拟代理:根据需要将资源消耗很大的对象进行延迟真正需要的时候进行创建。
  3. 保护代理:就是权限管理。
  4. 智能代理:就是增加额外功能。

静态代理

静态代理:代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。

例子:如何用代理计算汽车行驶时间

package com.example.proxy;

public interface Moveable {
   void move();
}

package com.example.proxy;

import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MoveAction;

public class Car implements Moveable {

	@Override
	public void move() {
		// TODO Auto-generated method stub
		for(int i = 0;i<1000;i++){
			System.out.println("汽车正在行驶");
		}
	}

}


静态代理实现方式

  • 继承
package com.example.proxy;

public class Car1  extends Car{

	@Override
	public void move() {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		super.move();//执行父类方法,也就是car方法
		long end = System.currentTimeMillis();
		System.out.println(end-start);
	}
	 

}

  • 聚合
package com.example.proxy;

public class Car2 implements Moveable {
	
	private Car c;

	public Car2(Car c) {
		super();
		this.c = c;
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		c.move();	
		long end = System.currentTimeMillis();
		System.out.println(end-start);
		
	}

}

继承和聚合哪种方式更适合

我们在上述的功能,在添加一个功能,来比较两种方式。



按照上面添加功能,每增加一个功能,就要多写一个类来继承。

下面是聚合方式,比较灵活,代码如下:

public class CarLog  implements Moveable {
	private Moveable c ;

	public CarLog(Moveable c) {
		super();
		this.c = c;
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("行车日志开始");
		c.move();
		System.out.println("行车日志结束");
		
	}
	

}

JDK动态代理

在上述功能中,如果每添加一个对象的代理,就要写一个代理类,这样的代理类会爆炸,我们就思考:动态产生代理,实现对不同类,不同方法的代理。




实现方式:就是在代理类和被代理类加事务处理器

代码如下:

public class Car implements Moveable {
	

	@Override
	public void move() {
		// TODO Auto-generated method stub
		for(int i = 0;i<1000;i++){
			System.out.println("汽车正在行驶");
		}
	}

}

事务处理器

public class CarProxy implements InvocationHandler {
	private  Object target;
	
	
	public CarProxy(Object target) {
		super();
		this.target = target;
	}


	/*
	 * (non-Javadoc)
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
	 * proxy  指被代理的类
	 * method 被代理的方法
	 * args 方法的参数
	 * 方法返回Object ,就是执行代理返回方法。
	 */

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		method.invoke(target);//这个方法是传入目标代理类,和参数,参数可以没有。
		long end = System.currentTimeMillis();
		System.out.println(end-start);
		return null;
	}

}

测试类

public class TestCar {

	@Test
	public void test() {
		/*Car c = new Car();
		Car2 c2 = new Car2(c);
		CarLog cl = new CarLog(c2);
		cl.move();*/
		Car c1 = new Car();
		Class<Car> c = (Class<Car>) c1.getClass();
		CarProxy cp = new CarProxy(c1);
		/*newProxyInstance参数
		 * loader   类加载器
		 * interfaces  实现接口
		 *  h   InvocationHandler
		 */
		Moveable m = (Moveable) Proxy.newProxyInstance(c.getClassLoader(),c.getInterfaces(),cp);
		m.move();
		
	}

}

JDK动态代理与CGLIB动态代理区别:

JDK动态代理:只能代理实现接口的类,,没有实现接口的类不能实现JDK的动态代理。

CGLIB动态代理:代理继承的类,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。

CGLIB代理代码如下:

首先导入cglib的jar包

public class Train {
           public  void move() {
			// TODO Auto-generated method stub
        	   System.out.println("火车正在开");

		}
}


package com.example.proxy;

import java.lang.reflect.Method;

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

public class CglibProxy implements MethodInterceptor {
	Enhancer enhancer = new Enhancer();
	/*
	 * 该方法来创建代理类
	 */
	public Object getProxy(Class cal){
		enhancer.setSuperclass(cal);
		enhancer.setCallback(this);
		return enhancer.create();
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
	 * arg0  目标类实例
	 * arg1 目标方法的反射对象
	 * arg2 方法参数
	 * arg3 代理器实例
	 */
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("日志开始");
		arg3.invokeSuper(arg0, arg2);//代理器实例调用父类方法
		return null;
	}

}


		CglibProxy c = new CglibProxy();
		Train  t = (Train) c.getProxy(Train.class);
		t.move();












































































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值