java动态代理

静态代理

  • 概念:代理和被代理对象在代理之前都是确定的,他们都实现了相同的借口或继承相同的继承类

java代码

public class Car implements Moveable{

	@Override
	public void move() {
		
		//实现开车
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println("汽车行驶中");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

使用继承方式实现代理

public class Car2 extends Car{

	@Override
	public void move() {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶");
		super.move();
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶,汽车行驶时间为"+(endtime-starttime)+"毫秒");
	}
	
}

使用聚合的方式实现代理

java代码

public class Car3 implements Moveable{
	private Car car;
	public Car3(Car car) {
		super();
		this.car = car;
	} 
	@Override
	public void move() {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶");
		car.move();
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶,汽车行驶时间为"+(endtime-starttime)+"毫秒");
	}
	
}
  • 继承和聚合方式比较
    • 如果有好几种状态需要代理,如日志,时间,事件等等,顺序又是经常打乱的,这样使用继承方式比较麻烦,所以使用聚合方式会比较好

动态代理

jdk动态代理

  • 创建一个类实现事务代理器,即InvocationHandler
  • 参数说明
    • proxy:被代理对象
    • method:被代理对象的方法
    • args:方法的参数
    • 返回值:
    • Object:方法的返回值
  • 只能代理实现了接口的类
    Java代码
public class TimeHandler implements InvocationHandler{
	
	private Object target;
	
	
	public TimeHandler(Object target) {
		super();
		this.target = target;
	}


	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		long startTime = System.currentTimeMillis();
		System.out.println("汽车开始行驶");
		method.invoke(target);
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶,汽车行驶时间为"+(endtime-startTime)+"毫秒");
		return null;
	}

}
/**
 * JDK动态代理测试类
 * @author Administrator
 *
 */
public class Test {
	public static void main(String[] args) {
		Car car =new Car();
		
		InvocationHandler h=new TimeHandler(car);
		Class<? extends Car> cls = car.getClass();
		
		
		/**
		 * loader 类加载器 
		 * interfaces 实现接口
		 * h invacationHandler
		 */
		Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
		m.move();
	}
}
public class Client {
	public static void main(String[] args) {
		final Actor actor=new Actor();
//		actor.basicAct(100f);
//		actor.dangeAct(500f);
		IActor proxyActor=(IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(),actor.getClass().getInterfaces() ,new InvocationHandler() {
			
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				Object rtValue=null;
				Float money =(Float) args[0];
				if("basicAct".equals(method.getName())) {
					if(money>10000) {
						rtValue=method.invoke(actor, money); 
					}
				}
				if("dangeAct".equals(method.getName())) {
					if(money>50000) {
						rtValue=method.invoke(actor, money);
					}
				}
				return rtValue;
			}
		});
		proxyActor.basicAct(20000);
		proxyActor.dangeAct(60000);
	}
}

动态代理

  • 含义:代理类在程序运行时创建的代理方式被称为动态代理
  • 它是一种这样的Class
    • 它是在运行时生成的class
    • 该class需要实现一组interface
    • 使用动态代理类时,必须实现InvocationHandler接口
    • 它的作用是不改变源码的基础上对已有方法进行增强。(它是AOP思想的实现技术)

使用cglib动态生成代理

  • 针对类来实现代理
  • 对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用
    • 要求:被代理的类不能是最终类,不能被final修饰
    • 提供者:第三方CGLIB
    • 涉及的类:EnHancer
    • 创建代理对象的方法:create(Class,Callback)
    • 参数的含义:
      • Class:被代理对象的字节码
      • Callback:如何代理,它和InvocationHandler的作用是一样的,它也是一个接口,一般使用该接口的子接口,MethodInterceptor
      • 在使用时,也是创建该接口的实现类

java代码

public class Client {
	public static void main(String[] args) {
		final Actor actor=new Actor();
		Actor cglibActor = (Actor) Enhancer.create(actor.getClass(),new MethodInterceptor() {
			/**
			 * 执行被代理对象的任何方法,都会经过该方法。它和基于接口动态代理的invocation方法的作用一模一样
			 * 方法的参数
			 * 		前面三个和invoke方法的参数和作用一样
			 * 		MethodProxy:当前执行方法的代理对象。一般不用
			 */
			public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
				Object rtValue=null;
				Float money =(Float) args[0];
				if("basicAct".equals(method.getName())) {
					if(money>10000) {
						rtValue=method.invoke(actor, money); 
					}
				}
				if("dangeAct".equals(method.getName())) {
					if(money>50000) {
						rtValue=method.invoke(actor, money);
					}
				}
				return rtValue;
			}
		});
		cglibActor.basicAct(20000);
		cglibActor.dangeAct(100000);
	}
}

动态代理的具体应用

连接池原理

  • 连接池使用完之后重新放回连接池
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值