Java 静态代理和动态代理 示例

本文详细介绍了静态代理和动态代理的概念及其实现方式。通过具体的Java代码示例,展示了如何创建代理类,以及它们在方法调用前后如何增强功能。静态代理通过手动创建代理类实现,而动态代理则利用Java反射API动态生成代理对象。
摘要由CSDN通过智能技术生成

只是自己学习时写的程序,只作为记录用,不是很正式的程序,也懒得百度一堆概念放在这里,没啥意思,直接上程序。

静态代理:

接口:

package StaticProxy;
public interface IPerson {
    void say();
}

实现类:
package StaticProxy;

public class Man implements IPerson {
    @Override
    public void say(){
        System.out.println("man say");
    }
}

静态代理类:
package StaticProxy;

public class StaticManProxy implements IPerson {
    //可以直接new对象,也可以通过外部new对象然后通过构造方法传递进来
    //private IPerson target = new Man();
    private IPerson target;
    //通过构造方法将目标对象传进来
    public StaticManProxy (IPerson target){
        this.target = target;
    }
   @Override
    public void say(){
        if(target!=null){
            System.out.println("man say invoked at :"+System.currentTimeMillis());
            target.say();
        }
   }

}

测试类:

package StaticProxy;

public class Test {
    public static void main(String[] args) {
        Man man = new Man();
        //直接通过代理类来实现增添方法
        StaticManProxy manProxy = new StaticManProxy(man);
        manProxy.say();
    }
}

体会:就是新建代理类,以你要代理的对象作为代理的成员变量,并用构造函数(或者其他get函数)将目标对象传入,在代理类中重写一些方法,增加内容等。

 

动态代理:

接口:

package DynamicProxy;

public interface IPerson {
    void say();
}
package DynamicProxy;

public interface Animal {
    public void eat();
}

 

实现类:

package DynamicProxy;

public class Man implements IPerson {
    @Override
    public void say(){
        System.out.println("man say");
    }
}
package DynamicProxy;

public class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("Cat love eating fash.");
    }
}

动态代理关键类:
package DynamicProxy;

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

public class DynamicProxy implements InvocationHandler {
    //可以直接new对象,也可以通过外部new对象然后通过构造方法传递进来
    //private IPerson target = new Man();
    private Object target = null;

    /**
     * 该方法返回一个指定接口的代理实例,接口以方法实参实现的接口为准
     * @param obj
     * @return
     */
    public Object getProxy(Object obj){
        this.target = obj;
        /**
         * 该方法有三个参数,loader参数定义代理类的加载
         * 器,interfaces代理类要实现的接口列
         * 表,h指派方法调用的调用处理程序
         */
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke (Object proxy, Method method, Object[]args)throws Throwable{
            Object result = method.invoke(target,args);
            return result;
    }
}

测试类:

package DynamicProxy;

public class Test {
    public static void main(String[] args) {
        /**
         * iPerson是生成的代理对象,与静态代理最大的不同就是,静太代理所实现的接
         * 口,封装的方法都是事先固定的而动态代理利用反射获取到类的所有信息,然
         * 后实时去创建代理对象,这样就实现了根据类的不同,创建不同代理对象
         */
        //动态代理只能用接口引用指向代理,而不能用传入的类引用执行动态
        IPerson iPerson = (IPerson) new DynamicProxy().getProxy(new Man());
        iPerson.say();
        //下面这段代码将会报错
//        Man man = (Man)new DynamicProxy().getProxy(new Man());
//        man.say();
        //再以animal类为例,体会动态代理的妙处。
        Animal animal = (Animal) new DynamicProxy().getProxy(new Cat());
        animal.eat();
    }

}

体会:关键点已经在程序里写出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值