静态代理和动态代理

静态代理

静态代理的实现比较简单,代理类通过实现与目标对象相同的接口,并在类中维护一个代理对象。通过构造器塞入目标对象,赋值给代理对象,进而执行代理对象实现的接口方法,并实现前拦截,后拦截等所需的业务功能

public class StaticProxy {
    private Person tagertObject = new Woman();

    /**
     * 对eat方法进行增强
     * @return
     */
    public String eat(){
        System.out.println(">>>>>>>before");
        tagertObject.eat("apple");
        System.out.println(">>>>>>>after");
        return "delicious";
    }
}

woman类请查阅关于oop和aop案例
测试代码

public static void test_static(){
        StaticProxy staticProxy = new StaticProxy();
        String eat = staticProxy.eat();
        System.out.println(eat);
    }

结果如下


静态代理对eat方法进行增强

动态代理

代理类在程序运行时创建的代理方式被成为动态代理, 然而静态代理的代理类在程序运行时已经编译完成, 这也是两者最大的区别. 动态代理有jdk代理和cglib代理, jdk代理案例在关于oop和aop中已经演示, 以下是cglib的代理方式
创建拦截器类, 实现MethodInterceptor, 哦, 忘了, 首先要加入cglib包

        
            cglib
            cglib
            3.2.5
        

cat类

public class Cat {
    public Cat(){
        System.out.println(">>>>>>>构造函数");
    }

    public void shout(){
        System.out.println(">>>>>>>>>>>喵喵喵 喵喵喵");
    }

    /**
     * 注意被final修饰的方法不能被动态代理
     */
    public final void jump(){
        System.out.println(">>>>>>>>>>>jump jump");
    }

}
public class TargetInterceptor implements MethodInterceptor {
    /**
     * 拦截方法
     * @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(">>>>>>>>before");
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println(">>>>>>>>after");
        return invoke;
    }
}

测试代码

public static void test_dynamic_cglib(){
        // 设置debug生成的class存放位置
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"E:\\class");
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Cat.class);
        enhancer.setCallback(new TargetInterceptor());
        Cat cat = (Cat) enhancer.create();
        cat.shout();
        cat.jump();
    }

测试结果

被final修饰的jump方法没有被代理

JDK动态代理和Gglib动态代理的区别

1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象
2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码, Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低
3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高
4.被代理类有接口用jdk代理, 无接口用cglib代理

你可能感兴趣的:(静态代理和动态代理)