Java静态代理和动态代理

代理功能在现实中也很常见,工厂生产货物,消费者购买商品,按道理消费者可以直接从厂家处购买,但是通常情况下,工厂不会直接销售给消费者,而是委托给代理商进行销售,顾客跟代理商打交道,而不直接与产品实际生产者进行关联,代理商在中间赚取差价。
java中也是实现类似的功能
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类
jdk动态代理在类实现了接口的情况下使用,cglib在类有继承的情况下使用

1、静态代理

创建1个接口类,1个实体类,1个代理类。

// 测试主类
public class Generic{
    public static void main(String[] args) {
        // 创建实体类Dog和Cat
        Animal dog = new Dog();
        // 分别传入Dog和Cat创建代理类
        AnimalProxy DogProxy = new AnimalProxy(dog);
        // 调用代理类
        DogProxy.eat();
        DogProxy.drink();
    }
}

// 公共接口,定义公共方法
interface Animal{
    void eat();
    void drink();
}
// 创建实体类Dog,重写Eat方法
class Dog implements Animal{
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

    @Override
    public void drink() {
        System.out.println("狗喝水");
    }
}
// 创建一个代理类,设置一个公共接口的属性,构造方法传入接口类,最后重写Eat、Drink方法,在里面拓展原有方法的功能
class AnimalProxy implements Animal{
    private Animal animal;

    public AnimalProxy(Animal animal) {
        this.animal = animal;
    }

    @Override
    public void drink() {
        System.out.println("开始准备食物!");
        this.animal.drink();
        System.out.println("食物已经吃完啦!");
    }

    @Override
    public void eat() {
        System.out.println("开始准备食物!");
        this.animal.eat();
        System.out.println("食物已经吃完啦!");
    }
}

优点是使用静态代理类可以在不修改原有代码的基础上,对原本的程序进行拓展或者重写,缺点是所有的类型都是预先定义好的,不够灵活,如果有多个方法需要添加某个拓展功能,需要重写多个方法,如果有多个接口就要分别写代理类实现。

2.动态代理

jdk动态代理,针对于实现接口的类,创建1个接口类,1个实体类(文中2个体现代码复用性),1个代理类。

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

public class Test{
    public static void main(String[] args) {
        Animal dog = new Dog();
        InvocationHandler dogHandler = new Home(dog);
        Animal dogAnimal = (Animal) Proxy.newProxyInstance(Dog.class.getClassLoader(),Dog.class.getInterfaces(), dogHandler);
        dogAnimal.eat();
        dogAnimal.drink();
        Plant tree = new Tree();
        InvocationHandler treeHandler = new Home(tree);
        Plant treePlant = (Plant) Proxy.newProxyInstance(Tree.class.getClassLoader(), Tree.class.getInterfaces(), treeHandler);
        treePlant.breath();
    }
}
// 创建接口Animal,定义Eat方法
interface Animal{
    void eat();
    void drink();
}
// 创建接口Plant,定义Breath方法
interface Plant{
    void breath();
}
// 创建实体类Dog,实现Animal接口,重写Eat方法
class Dog implements Animal{
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

    @Override
    public void drink() {
        System.out.println("狗喝水");
    }
}
// 创建实体类Tree,实现Plant接口,重写Breath方法
class Tree implements Plant{
    @Override
    public void breath() {
        System.out.println("植物呼吸空气");
    }
}
// 创建动态代理实现InvocationHandler接口,创建Object属性target,构造函数传入目标类,重写invoke方法,通过method.invode(target,args)调用target的方法
class Home implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始准备食物!");
        method.invoke(target,args);
        System.out.println("食物已经吃完啦!");
        return null;
    }
}
cglib动态代理,首先使用maven引入cglib包,创建1个实体类,1个代理类
package org.fssx;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

// 运行主体类
public class Test
{
    public static void main( String[] args )
    {
        MyProxy myProxy = new MyProxy();
        Dog dog = (Dog) myProxy.getProxy(Dog.class);
        dog.Eat();
    }
}
// 被代理实体类
class Dog{
    void Eat(){
        System.out.println("狗吃肉");
    }
}
// 代理类
class MyProxy implements MethodInterceptor{
	// 实例化时创建
    private final Enhancer enhancer = new Enhancer();
    public Object getProxy(Class cls){
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开始准备食物!");
        methodProxy.invokeSuper(o, objects);
        System.out.println("食物已经吃完了!");
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值