代理模式

静态代理StaticProxy.java

package com.csdn.proxy;

/**
 * 静态代理
 * 对原有类的现有方法进行增强,静态代理还是比较容易理解的
 * 要素:
 * 1.共同的接口或者抽象类
 * 2.原有类(必须实现共同的接口或者继承共同的抽象类)
 * 3.代理类(必须实现共同的接口或者继承共同的抽象类,且要想办法把原有类对象传过去,用依赖倒置原则)
 * 代理模式常用于:
 * 1.日志记录
 * 2.事务处理
 */
//共同的接口类(推荐尽量多的用接口,面向接口编程)
interface CommonAction{
    public void method();
}

//原有类实现共同的接口类
class MyClass implements CommonAction{

    @Override
    public void method() {
        System.out.println("这是我原有的方法");
    }
}
//代理类实现共同的接口类,并把原有类当成类属性,通过构造方法参数值传过来
class Proxy implements CommonAction{

    CommonAction object;

    public Proxy(CommonAction object) {
        this.object = object;
    }

    @Override
    public void method() {
        this.before();
        object.method();
        this.after();
    }
    private void before(){
        System.out.println("做事之前记日志");
    }

    private void after(){
        System.out.println("做事之后记日志");
    }
}
public class StaticProxy {
    public static void main(String[] args) {
        CommonAction old = new MyClass();
        //此时就对原有类中的方法进行了增强
        CommonAction proxy  = new Proxy(old);
        proxy.method();

    }
}

jdk动态代理 JdkProxy.java

package com.csdn.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 动态代理:代理类动态生成
 * jdk动态代理:提供一个中间类handler,这个中间类必须实现InvocationHandler接口,要实现其中的invoke方法
 * 而后使用时,jdk的reflect包中的Proxy会提供调用这个中间类的方法,这个方法的返回对象为代理类对象
 */
//共同的接口类(推荐尽量多的用接口,面向接口编程)
interface CommonAction1{
    public void method();
}

//原有类实现共同的接口类
class MyClass1 implements CommonAction1{

    @Override
    public void method() {
        System.out.println("这是我原有的方法");
    }
}
//jdk动态代理的中间类,必须实现InvocationHandler接口,实现invoke方法
//注意:这个类并不是真正的代理类。只是真正的代理类是由它生成的
//具体如何调用,由jdk说了算。jdk是用反射包中的Proxy.new开头(newProxyInstance)的方法 来实现的
class DynamicProxyHandler implements InvocationHandler {

    CommonAction1 object;

    public DynamicProxyHandler(CommonAction1 object) {
        this.object = object;
    }

    private void before(){
        System.out.println("做事之前记日志");
    }

    private void after(){
        System.out.println("做事之后记日志");
    }

    /**
     *
     * @param proxy 生成的动态代理对象
     * @param method 要代理的方法
     * @param args 要代理的方法参数
     * @return 要代理的方法执行完成后返回的参数
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        this.before();
        method.invoke(this.object,args);
        this.after();
        return null;
    }
}

public class JdkProxy {
    public static void main(String[] args) {
        ClassLoader classLoader = CommonAction1.class.getClassLoader();
        //中间类对象。注意把原有类对象通过构造方法也可以通过set方法传进去
        DynamicProxyHandler handler = new DynamicProxyHandler(new MyClass1());
        //第1个参数为类加载器(动态生成的代理类到时用什么加载器加载)
        //第2个参数共同的接口的class(字节码对象),为动态生成的代理类与原有类都实现的同一个接口
        //第3个参数为jdk要求的InvocationHandler接口的实现类
        //返回对象为动态代理类的对象
        CommonAction1 proxy = (CommonAction1)java.lang.reflect.Proxy.newProxyInstance(classLoader,new Class[]{CommonAction1.class},
                handler);
        //调用动态代理对象的方法
        proxy.method();

    }
}

cglib动态代理CglibProxy.java

package com.csdn.proxy;

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

import java.lang.reflect.Method;

/**
 * cglib动态代理。与jdk动态代理实现类似。只是jdk是基于接口的,但cglib是基于继承的(方法)
 * 要素:
 * 1.原始类(不能用final修饰)
 * 2.handler类,继承于cglib的MethodInterceptor类
 * 3.生成代理类并调用
 * 具体代理的是类中的哪个方法,由原有类调用时调用哪个方法来决定
 * 必须要导入2个jar包
 * 1)cglib-2.2.2.jar
 * 2)asm-3.3.1.jar(不要忘了)
 */

class OldClass{
    public void myMethod1(){
        System.out.println("我的第1个方法");
    }
    public void myMethod2(){
        System.out.println("我的第2个方法");
    }
}

class CglibProxyHandler implements MethodInterceptor {

    /**
     * 类似于jdk的invoke方法
     * @param o 代理类对象
     * @param method 原始类中某方法
     * @param objects 原始类中的某方法参数
     * @param methodProxy 代理类类对象中的代理方法
     * @return 代理类的对象
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglig:前置增强");
        System.out.println(o.getClass());
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("cglig:后置增强");
        System.out.println(methodProxy.getSuperName());
        return object;
    }
}

public class CglibProxy {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        //设置需要被代理的对象
        enhancer.setSuperclass(OldClass.class);
        //设置hander
        enhancer.setCallback(new CglibProxyHandler());
        OldClass o = (OldClass)enhancer.create();
        //调用哪个方法,就对哪个方法进行增强
        o.myMethod2();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值