JavaWeb学习笔记之动态代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lsf921016/article/details/69219954

代理是实现AOP(Aspect oriented program,面向切面编程)的核心和关键技术。

1.什么是代理(proxy)?

代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类负责为委托类预处理消息,过滤消息并转发消息以及进行消息被委托类执行后的后续处理。为了保持行为的一致性,代理类和委托类通常会实现相同的接口

  • 静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,也就是说在程序运行前代理类的.class文件就已经存在。
  • 动态代理:在程序运行时运用反射机制动态创建生成。

这里写图片描述

紫色线代表继承关系,红色线代表调用关系

2. 动态代理

  • JVM可以在运行期动态生成类的字节码,该类往往被用作动态代理类。
  • JVM生成的动态类必须实现一个或多个接口,所以这种只能用作具有相同接口的目标类的代理。
  • CGLIB库可以动态生成一个类的子类,一个类的子类也可作为该类的代理,这个可用来为没有实现接口的类生成动态代理类。
  • 代理类可在调用目标方法之前、之后、前后、以及处理目标方法异常的catch块中添加系统功能代码。

3. 创建代理对象

创建代理对象的作用:动态地生成一个类,该类实现了A,B接口,然后创建该类的对象。
需要创建出一个新类,被ClassLoader加载进方法区。

Proxy.newProxyInstance()方法的三大参数:
1. ClassLoad:
2. Class[] interfaces:需要实现的接口们
3. InvocationHandler: 每次调用都会执行invoke()方法内的代码

//参数一
        ClassLoader loader=this.getClass().getClassLoader();

        //参数二
        Class[] interfaces={A.class,B.class};

        //参数三
        InvocationHandler invocationHandler=new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("invocation");
                return null;
            }
        };

        //创建一个实现了A接口和B接口的代理对象
        Object proxy= Proxy.newProxyInstance(loader,interfaces,invocationHandler);

        //强转
        A a=(A)proxy;
        B b=(B)proxy;
        System.out.println(proxy.getClass().getName());

InvocationHandler接口只有一个invoke方法,每次调用代理类的方法,即调用了InvocationHandler对象的invoke方法

invoke方法涉及三个要素:

  • 代理对象
  • 代理对象调用的方法
  • 方法接受的参数
    注:Object类的hashCode,equals,toString方法交给invoke,其他的Object类的方法,Proxy有自己的实现。
    调用处理器工作原理

4.实现一个代理工厂模式

需求:男服务员实现服务员接口,在进行服务员的所有方法时,都被beforeAdvice和AfterAdvice装饰

/**@author
 * 用来生成代理对象
 * 它需要所有的参数:
 * 1.目标对象
 * 2.增强内容
 *
 * 代理工厂使用过程:
 *
 * 1.创建代理工厂
 * 2.设置三个成员变量:
 *  目标对象
 *  前置增强
 *  后置增强
 * 3.调用getProxy得到代理对象
 *    执行代理对象的方法时:
 *    执行BeforeAdvice的before()
 *    执行目标对象的目标方法
 *    执行AfterAdvice的after()
 */
public class ProxyFactory {
    private Object targetObject;//目标对象
    private BeforeAdvice beforeAdvice;
    private AfterAdvice afterAdvice;

    //用来生成代理对象
    public Object getProxy(){
        //给出创建Proxy对象的三大参数
        ClassLoader classLoader=this.getClass().getClassLoader();
        Class[] interfaces=targetObject.getClass().getInterfaces();
        InvocationHandler h=new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //调用代理对象的方法时会执行这里的内容
                if (beforeAdvice!=null){
                    beforeAdvice.before();
                }
                Object res=method.invoke(targetObject,args);

                if (afterAdvice!=null)
                    afterAdvice.after();

                return res;

            }
        };
        Object proxyObject= Proxy.newProxyInstance(classLoader,interfaces,h);
        return proxyObject;
    }

    public Object getTargetObject() {
        return targetObject;
public interface Waiter {
    public void serve();
    public void washing();
    public void cashing();
}
public class ManWaiter implements Waiter {
    @Override
    public void serve() {
        System.out.println("serving");
    }

    @Override
    public void washing() {
        System.out.println("washing dishes");
    }

    @Override
    public void cashing() {
        System.out.println("cashing money");
    }

}
public interface BeforeAdvice {
    public void before();
}
public interface AfterAdvice {
    public void after();
}

运行:

public class demo {
    public static void main(String[] args) {
        ProxyFactory factory=new ProxyFactory();
        factory.setTargetObject(new ManWaiter());
        factory.setBeforeAdvice(new BeforeAdvice() {
            @Override
            public void before() {
                System.out.println("this is before .........");
            }
        });
        factory.setAfterAdvice(new AfterAdvice() {
            @Override
            public void after() {
                System.out.println("this is after");
            }
        });

        Waiter waiter= (Waiter) factory.getProxy();
        waiter.serve();
        waiter.washing();
        waiter.cashing();
    }
}

输出:

this is before ………
serving
this is after
this is before ………
washing dishes
this is after
this is before ………
cashing money
this is after

猜你喜欢

转载自blog.csdn.net/lsf921016/article/details/69219954