设计模式--代理模式

静态代理

定以一个学生类,学生有上课和写作业两种行为

public interface Student {
    public int attendClass();

    public void doHomework();
}


public class StudentImpl implements Student{
    @Override
    public int attendClass() {
        System.out.println("学生上课");
        return 1;
    }

    @Override
    public void doHomework() {
        System.out.println("学生写作业");
    }
}

定义学生代理类

public class StudentProxy implements Student{
    private Student student;
    public StudentProxy(Student student) {
        this.student = student;
    }

    @Override
    public int attendClass() {
        System.out.println("坐车上学");
        student.attendClass();
        return 0;
    }

    @Override
    public void doHomework() {
        System.out.println("坐车回家");
        student.doHomework();
    }
}

测试

@Test
    public void testStaticProxy() {
        StudentProxy studentProxy = new StudentProxy(new StudentImpl());
        studentProxy.attendClass();
        studentProxy.doHomework();
    }
    输出:
    坐车上学
	学生上课
	坐车回家
	学生写作业

学生代理类对学生上学和写作业两个动作进行了增强,但是耦合性太强,一个代理类只为一个代理对象服务,代理类需要实现代理对象的接口,维护较为麻烦。

JDK动态代理

代理类实现InvocationHandler接口,在invoke中做增强,运行时生成代理类实现接口进行增强
前提:需要代理类实现实现接口

public class StudentProxyJdk implements InvocationHandler {
    // 需要代理的目标类对象
    public Object student;

    public StudentProxyJdk(Object student) {
        this.student = student;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object ret = null;
        if ("attendClass".equals(method.getName())) {
            System.out.println("坐车上学");
            // 调用代理对象的接口
            ret = method.invoke(student, args);
        } else if ("doHomework".equals(method.getName())) {
            System.out.println("坐车回家");
            method.invoke(student, args);
        }
        return ret;
    }
}

测试

 @Test
    public void testJdkProxy() {
        Student student = (Student) Proxy.newProxyInstance(StudentImpl.class.getClassLoader(), StudentImpl.class.getInterfaces(), new StudentProxyJdk(new StudentImpl()));
        student.attendClass();
        student.doHomework();
        saveProxy("/xx/xx");
    }

// 生成运行时的代理类
private void saveProxy(String path) {
        byte[] $Proxies = ProxyGenerator.generateProxyClass("$Proxy2", StudentImpl.class.getInterfaces());
        FileOutputStream fileOutputStream = null;
        try {
             fileOutputStream = new FileOutputStream(new File(path + "$Proxy2.class"));
             fileOutputStream.write($Proxies);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

运行时生成的代理类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import com.wxx.staticProxy.Student;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy2 extends Proxy implements Student {
    private static Method m1;
    private static Method m4;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy2(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void doHomework() throws  {
        try {
            super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int attendClass() throws  {
        try {
            return (Integer)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("com.wxx.staticProxy.Student").getMethod("doHomework");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.wxx.staticProxy.Student").getMethod("attendClass");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

cglib动态代理

通过运行时继承代理对象生成代理类来进行增强,不需要实现接口。
使用前需要引入依赖

		<dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

定义一个Star对象

public interface Star {
    void sing();
    int dance();
}
public class SuperStart implements Star{
    @Override
    public void sing() {
        System.out.println("明星唱歌");
    }

    @Override
    public int dance() {
        System.out.println("明星跳舞");
        return 0;
    }
}

定义拦截器

public class StarCglibInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, org.springframework.cglib.proxy.MethodProxy methodProxy) throws Throwable {
        Object ret = null;
        if ("sing".equals(method.getName())) {
            System.out.println("收钱");
            ret = methodProxy.invokeSuper(o, objects);
        } else if ("dance".equals(method.getName())) {
            System.out.println("收钱");
            methodProxy.invokeSuper(o, objects);
        }
        return ret;    }
}

测试

@Test
    public void testCglibProxy() {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/xxx/xxx/");
        CglibInterceptor cglibInterceptor = new CglibInterceptor();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(SuperStart.class);
        enhancer.setCallback(cglibInterceptor);
        Star star = (Star) enhancer.create();
        star.sing();
        star.dance();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值