代理

代理(Proxy)

 

现在要扩展eat方法的功能,

 

 

静态代理(方法的代理)

IPeople接口有eat()方法

public interface IPeople{

     void  eat();      
}

people类实现IPeople

public class People implements IPeople {
    @Override
    public void eat() {
        System.err.println("我吃饭了");
    }
}

代理people

public class ProxyPeop implements IPeople{

    private IPeople target;//target就是要代理的目标对象

    public ProxyPeop(IPeople target )
    {
        this.target = target;
    }

    @Override
    public void eat() {
        //我要洗手
        System.out.println("我要洗手");
        target.eat();
        //我要刷牙
        System.out.println("我要刷牙");
    }
}

测试

 @Test
    public void cc()
    {
        IPeople target = new People();
        ProxyPeop proxyPeop = new ProxyPeop(target);
        proxyPeop.eat();
    }

不足:有上述代码可知,访问的方法变为代理对象的方法,但真正eat方法还是有目标对象执行。这样就可以不改动原来的代码,,来增加功能。

可以看出,静态代理,依赖于接口,接口变动,,目标对象和代理对象都得改变。且代理类在编译期已经存在,有自己编写。并且如果有增删改查四个

方法在代理类中还是有很多重复代码,,复用性不高。

 

动态代理(代理的类级别)

代理类不再需要实现目标接口,代理对象由运行时生成,

显而易见,不需要写重复的代码。运行时自动生成代理对象

public class DynamicProxyPeople {

    private IPeople target;

     People people = new People();// 目标对象
/*Proxy.newProxyInstance() ClassLoader 类加载器 interface[] 目标对象实现的接口 InvocationHandler InvocationHan实现 * */ public IPeople getProxy() { target = (IPeople)Proxy.newProxyInstance(DynamicProxyPeople.class.getClassLoader(),people.getClass().getInterfaces(),
new InvocationHandler() { /* * proxy 目标对象 * method 目标对象的方法 * args 参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.err.println(method.getName());//方法名 System.out.println("我要洗手"); method.invoke(people); System.out.println("我要刷牙"); return null;//f方法返回值 } }); return target; } }

 

 

cglib代理

上述两种方式都需接口,但是我们不想写接口呢。cglib就不需要

cglib叫做继承代理,就是生成一个继承了目标对象的代理类(子类)。(可以在运行期间扩展java类和接口)

public class CglibProxy implements MethodInterceptor {


    private Object target;

    public CglibProxy(Object target)
    {
        this.target = target;
    }

    public People getProxy()
    {
        Enhancer enhancer = new Enhancer();
        //工具类  设置父类
        enhancer.setSuperclass(People.class);
        //设置回调  即 intercept函数  增强代码
        enhancer.setCallback(this);
        //创建子类
        Object o = enhancer.create();

        return (People) o;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        System.out.println("我要洗手");
        method.invoke(target,args);
        System.out.println("我要刷牙");

        return null;
    }
}

spring集成了cglib所以需导入spring-core包,生成的代理对象父类为目标对象

posted @ 2019-09-01 22:03  古月大叔  阅读(236)  评论(0编辑  收藏  举报