
基本: 需要具有面向对象的设计思想,多态性思想,反射思想;
Java动态代理机制的出现使Java开发人员无需手动编写代理类. 他们可以简单地获取一组接口并委托类对象以动态获取代理类. 代理类将负责将所有方法调用分派给委托对象以进行反射执行. 在调度执行过程中java设计模式代码,开发人员还可以根据需要调整委托类对象及其功能. 这是一个非常灵活和灵活的代理框架. 阅读本文之后,读者将对Java动态代理机制有更深入的了解. 本文首先从Java动态代理的运行机制和特点分析其代码,并推导动态生成类的内部实现.
代理模式的基本概念和分类
代理模式: 为其他对象提供代理,以控制对该对象的访问. 代理对象充当中介,并且可以删除服务或添加其他服务,或引用其他服务: “代理类负责为委托类预处理消息,过滤消息并转发消息,并在代理对象之后执行后续处理. 消息由委托类执行. “
代理模式在开发中的应用场景
远程代理: 为不同地理位置的对象提供LAN代表对象.
虚拟代理: 根据需要延迟消耗大量资源的对象,并在真正需要它们时创建它们. 例如,在网页中java设计模式代码,首先显示文本,然后显示图片.
保护代理: 控制不同用户的访问权限. 例如,添加,删除,修改和检查之类的操作只能在成功注册客户之后执行.
智能参考代理: 向目标代理提供其他服务.
代理模式的实现
用继承和聚合实现动态代理更好吗?
public interface Moveable {
public void move();
}
public class Car implements Moveable{
@Override
public void move() {
try {
Thread.sleep(new Random().nextint(1000));
System.out.println("……行驶中……");
}
catch(InterruptedException e) {
// TODO Auto-generated catch block
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)+"ms");
}
}
通过继承实现代理
Moveablecar2 = newCar2();
car2.move();
聚合以实现代理

Carcar = newCar();
Moveablem = newCar3(汽车);
m.move();
摘要
继承的使用不够灵活. 当功能叠加时,代理类只能膨胀.
使用聚集,代理可以相互传递并灵活地组合代理;
public class CarLogProxy extends Car{
@Override
public void move()
{
//分离代码,增加业务逻辑
long startTime=System.currentTimeMillis();
System.out.println("日志开始……");
super.move();
long endTime=System.currentTimeMillis();
System.out.println("日志结束……");
}
}
public class CarTimeProxy implements Moveable {
public CarTimeProxy(Car car)
{
super();
this.car=car;
}
private Carcar;
@Override
public void move() {
//分离代码,增加业务逻辑
long startTime=System.currentTimeMillis();
System.out.println("汽车开始行驶……");
car.move();
long endTime=System.currentTimeMillis();
System.out.println("汽车结束行驶……时间:"+(endTime-startTime)+"ms");
}
}
@Test:
Car car =new Car();
CarTimeProxy ctp=new CarTimeProxy(car);
CarLogProxy clp=new CarLogProxy(ctp);
clp.move();
//还可以通过接口相互传递代理实例
CarLogProxy clp1=new CarLogProxy(car);
CarTimeProxy ctp1=new CarTimeProxy(clp1);
ctp1.move();
JDK动态代理和CGlib动态代理
JDK动态代理
代理实现
如果不同的对象想要实现相同的代理类,该怎么办?
这时,您可以尝试将其集成到相同的代理类中-----动态代理: 为不同的类/不同的方法实现代理;
一般过程如下:

Java动态代理类位于java.lang.reflect包中. 通常,主要涉及以下两个类:
(1)InterfaceInvocationHandler: 此接口中仅定义了一种方法: Publicobjectinvoke(Objectobj,Methodmethod,Object [] args)
obj: 通常指代代理类
方法: 是要委派的方法
args是此方法的参数数组.
此抽象方法是在代理类中动态实现的.
(2)代理: 此类是动态代理类
statixObjectnewProxyInstance(ClassLoaderloader,Class []接口,InvocationHandlerh)
返回糖苷类的实例. 返回的代理类可以用作代理类(可以在接口中使用代理类声明的方法);
实施示例:
@ TimeHandler
public class TimeHandler implements InvocationHandler {
public TimeHandler(Object target) {
super();
this.target = target;
}
private Objecttarget;
/*
* 参数:
* proxy 被代理对象
* method 被代理对象的方法
* args 方法的参数
*
* 返回值:
* Object 方法返回值
*/
@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)+"ms");
return null;
}
}
@被代理类的接口
public interface Moveable {
public void move();
}
@被代理的类
public class Car implements Moveable{
@Override
public void move() {
try {
Thread.sleep(new Random().nextint(1000));
System.out.println("……行驶中……");
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@测试
public class Test {
/**
* JDk动态代理的测试类
*/
public static void main(String[] args) {
Car car=new Car();
InvocationHandler h=new TimeHandler(car);
Class<?>cls=car.getClass();
/*
* loader 类加载器
* interfaces 实现接口
* h InvocationHandler
*/
Moveable m=(Moveable)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),h);
m.move();
}
}
&&测试结果

总结
DynamicProxy是一个类似这样的类:
它是在运行时生成的类. 此类需要实现一组接口. 使用动态代理类时,它必须实现InvocationHandler接口.

JDK动态代理的一般步骤
1. 创建一个实现接口InvocationHandler的类,该接口必须实现invoke()
2. 创建代理类和接口
3. 调用Proxy的静态方法来创建代理类
newProxyInstance(ClassLoaderloader,Class []接口,InvocationHandlerh)
4. 通过代理调用方法

CGlib动态代理的实现
代理实现
@介绍cglib-node-2.2.jar软件包
@CglibProxy拦截类实现接口MethodInterceptor: 重写拦截拦截方法
public class CglibProxy implements MethodInterceptor {
private Enhancerenhancer=new Enhancer();
public Object getProxy(Class cl)
{
//设置创建子类的类
enhancer.setSuperclass(cl);
enhancer.setCallback(this);
return enhancer.create();
}
/*
* 拦截所有目标类方法的调用
* object 目标类的实例
* m 目标方法的反射对象
* args 方法的参数
* proxy 代理类的实例
*
*/
@Override
public Object intercept(Object obj, Method m,Object[] args, MethodProxy proxy)throws Throwable
{
System.out.println("日志开始……");
//代理类调用父类的方法
proxy.invokeSuper(obj, args);
System.out.println("日志结束……");
return null;
}
}
@被代理类火车
public class Train {
public void move()
{
System.out.println("火车行驶中……");
}
}
@测试类
public class Test {
/**
* cglibProxy动态代理测试类
*/
public static void main(String[] args) {
CglibProxy proxy=new CglibProxy();
Train t=(Train)proxy.getProxy(Train.class);
t.move();
}
}

##测试结果:

总结
使用CglibProxy实现动态代理的一般步骤
1. 创建一个实现MethodInterceptor接口并覆盖拦截方法的类.
2. 创建代理类
3. 调用代理类的自定义方法以获取代理实例
4. 通过代理实例调用代理类要执行的方法
比较摘要
JDK动态代理
1. 只有实现接口的类才能被代理.
2,未实现接口的类无法实现JDK的动态代理
CGlib动态代理
1. 实现类的代理
2. 生成执行目标类的子类,并通过方法拦截技术拦截父类方法的所有调用.
模拟代理生成步骤
思考:
实现功能: 通过代理的newProxyInstance返回代理对象
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-154285-1.html
就晓得淘宝马上要短命了
看来只能只能当月光族了
妈的