代理

Posted on 2019-07-24 14:52  Fouro'clock  阅读(176)  评论(0)    收藏  举报

代理主要分为两种方式:静态代理和动态代理

一、静态代理

  静态代理类似与java中的组合,代理类与被代理类实现同一个接口,代理类把被代理类组合尽力,在执行前后可以做一些其他的操作。

package staticproxy;


public class StaticProxyDemo {
    public static void main(String[] args) {
        ProxyCat proxyCat = new ProxyCat(new Cat());
        proxyCat.eat();
    }
}

/**
 * 创建一个接口类
 */
interface Animal{
    void eat();
}

class Cat implements Animal{
    @Override
    public void eat() {
        System.out.println("i am a cat, i want to eat fish");
    }
}

class ProxyCat implements Animal {

    Animal animal;

    ProxyCat(Animal animal){
        this.animal = animal;
    }

    @Override
    public void eat() {
        System.out.println("we ready fish for Cat to eat");
        animal.eat();
        System.out.println("eat over,we clean here");
    }
}

二、动态代理 动态代理分为jdk自带动态代理个cglib代理。

  1、jdk动态代理

  

package jdkproxy;

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

/**
 * jdkproxy
 *
 * @author lfm on 2019/7/24
 */
public class JdkProxy {
    public static void main(String[] args) {
        Animal animal = new Cat();
        InvocationHandler in = new ProxyDynamic(animal);
        Animal proxy =  (Animal)Proxy.newProxyInstance(Animal.class.getClassLoader(),Cat.class.getInterfaces(),in);
        proxy.eat();
    }
}


interface Animal {
    void eat();
}

class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("i am ready to eat!");
    }
}

//定义时间处理器
class ProxyDynamic implements InvocationHandler { Object obj; ProxyDynamic(Object o) { this.obj = o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("prepare food"); method.invoke(obj, args); System.out.println("clean desk"); return null; } }

  jdk动态代理缺点:目标对象一定要实现一个接口,而且不是Object,不然就不能使用动态代理。

  2、cglib 代理,解决了jdk动态代理的缺点,目标对象不需要一定实现一个接口。

      (引用):CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供        方法的interception(拦截)。 

           CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式        和指令集都很熟悉。

  使用方法:

  1)首先要引入一个包cglib  jar。

  注意:

  1)代理的类不能是final的。

  2)代理类的方法不能是final/static的,否侧不会被拦截。

  

package cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * demo class
 *
 * @author lfm on 2019/7/24
 */

public class DemoClass {
    public void say(){
        System.out.println("i am ready to say");
    }

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(DemoClass.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("i am be proxy start");
                Object result = methodProxy.invokeSuper(o,args);
                System.out.println("i am be proxy end");
                return result;
            }
        });
        DemoClass demoClass = (DemoClass) enhancer.create();
        demoClass.say();
    }
}

 

事件处理器