静态代理
- 概念:代理和被代理对象在代理之前都是确定的,他们都实现了相同的借口或继承相同的继承类
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);
}
}
动态代理的具体应用
连接池原理
- 连接池使用完之后重新放回连接池