java中代理模式以及new和newInatance()的区别

来源:互联网 发布:360软件管家电脑版 编辑:程序博客网 时间:2024/05/21 14:54

在java开发过程中经常使用到代理模式,其中代理模式分为静态代理动态代理

代理模式主要通过代理来实现对外功能,但是代理类本身并不实现功能,主要通过调用被代理的对象来实现功能。


静态代理:已经写好的代码,运行时就已经存在相应的class文件。

动态代理:利用java中的反射机制实现。


静态代理:

public Interface A{    public void x();    public void y();}
public Class M implement A{
    public void x(){
        System.out.println("1111");
    }
    public void y(){
        System.out.println("2222");
    }
}
public Class N implement A{
    public A a;
    public M(A a){ 
        this.a = a;
    }
    public void x(){
        a.x();
    }
    public void y(){
        a.y();
    }
}
public Class Main{
    N n = new N(new M());
    n.x();
    n.y();
}

因此可以说类N是类M的代理,但是类N的函数并没有自己实现逻辑功能,而是调用了类M的函数功能。在以后的修改过程中,只修修改类M的逻辑,而对外看来代理类N没有任何改变。但一个代理类只能为一个代理功能服务,一次会造成代码冗余。

动态代理:

动态代理利用java的反射机制,生成任意类型的代理类。有java.long.reflect包中的invocationHandler接口实现。

InvocationHandler接口的使用:

public interface InvocationHandler{    public Object invoke(Object proxy, Method method, Object args[]) throws Throwable;}

三个参数分别为需要代理的类,调用的方法名和方法参数。

Proxy类:该类是一个代理类,可以为一个或多个接口实现代理

public static Object newProxyInstance(classLoader loader, Class<?>[] interface, InvacationHandler h) throws IllegalArgumentException
类加载器+所有的接口+InvacationHandler的子类实现

public interface A{    public void x();}
public Class M implement A{
    public void x(){
        System.out.println("1111");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
Import java.lang.reflect.Proxy;
public Class N implements InvocationHandler{
    private Object target;
    public Object createProxyInstance(Object target){
        this.target = target;
        return Proxy.newProxyInstance(target.getClass.getClassLoader(), target.getClass.getInterface(), this);
    }
//上述的this代指N这个类,因为它继承了InvocationHandler,自动调用invoke方法
public void invoke(Object proxy, Method method, Object args[]</span>){
    Object result = null;
    try{
        result = method.invoke(target, args);
    catch{
    }finally{
    }
    return result;
    }
}
public Class Main{
    N n = new N();
    A a = (A)n.createProxyInstance(new M());
    a.x();
}

还有一种通过cglib实现的动态代理,还没看懂,以后再说。


在动态代理过程中使用里java的反射机制:class.getClass()等方式。

一般来说,通过Class.froName()的静态方式获得动态加载类,随后通过调用newInstance()静态方法实例化对象。如果仅仅使用Class.forName()是没有意义的,因为没有实例化具体的对象。通过实例化对象后,可以利用具体对象来获得相应的方法、内部变量等对象,从而完成 进一步操作,具体请百度。


这里面需要注意new和newInstance()的不同,前者是关键字,而后者是一个方法,而这个方法只能调用无参的构造函数。

Class.forName()返回一个类;

Class.forname().newInstance()返回对象;

在使用new的时候允许类没有被加载,但是在使用newInstance()方法时需要保障  类已经被加载+类已经被连接  完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。





0 0
原创粉丝点击