【Java 笔记】静态代理和动态代理

静态代理

  • 静态代理需要代理对象和被代理对象都实现同一个接口或者父类
  • 通过将接口或父类的实例(被代理对象)聚合到代理工厂的方式
  • 在代理类中实现对被代理对象的方法调用

缺点:每个代理类只能代理一类对象,当需要代理多个类时,会需要写很多个代理工厂,这样代码扩展性不佳

public class StaticProxyTest {
    public static void main(String[] args) {
        Target target=new Target();
        TargetProxyFactory proxyF=new TargetProxyFactory(target);
        proxyF.method();
    }
}

interface Infe{
    void method();
}

class Target implements Infe{

    @Override
    public void method() {
        System.out.println("我是目标对象");
    }
}

class TargetProxyFactory implements Infe{
    public Infe target;

    public TargetProxyFactory(Infe target) {
        this.target=target;
    }

    @Override
    public void method() {
        target.method();
    }
}

利用反射机制实现动态代理

  • 动态代理代理对象不需要实现接口,只需要被代理对象实现同一个接口
  • 利用JDK中,java.lang.reflect.Proxy 的newProxyInstance()方法返回一个代理对象(被代理对象的接口实例)
public class AutoProxyTest {
    public static void main(String[] args) {
        AutoTarget target=new AutoTarget();
        AutoProxyFactory factory=new AutoProxyFactory(target);  //构造代理工厂时传入被代理的目标对象
        Infe1 proxyInstance = (Infe1)factory.getProxyInstance();//获得代理对象
        Object res=proxyInstance.method();//调用被代理对象的方法,接收返回值
       //== int res=proxyInstance.method();
        System.out.println(res);
    }
}

//被代理对象实现的接口
interface Infe1{
     int method();
}

//被代理对象
class AutoTarget implements Infe1{

    @Override
    public int method() {
        System.out.println("我是目标对象");
        return 666;
    }
}

//代理工厂
class AutoProxyFactory  {
    public Object target;//传入所需被代理的对象

    public AutoProxyFactory(Object target) {
        //构造代理工厂时传入被代理的目标对象
        this.target = target;
    }

    public Object getProxyInstance(){
        //-----根据传入的被代理对象动态生成对应的代理对象

        //1.ClassLoader :指定被代理对象的类加载器;
        //2.Interface :指定被代理对象实现的接口;
        //3.InvocationHandler :事件处理:执行目标方法时,会触发事情处理器方法,需要重写其invoke()方法
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //Object proxy:生成的代理对象
                // Method method:被代理对象的方法
                //Object[] args:被代理类调用的方法的参数
                Object res= method.invoke(target,args);
              return res;
            }
        });
    }
}

cglib 动态代理

  • 上一种动态代理的被代理对象必须有实现的接口,对于没有接口的类不可以使用该动态代理。
  • cglib代理是利用创建被代理对象的子类来实现代理,所以当目标对象没有实现接口时,可以使用cglib代理。
    但是cglib代理的目标对象不可以为final类,final类无继承类

步骤:

  • 1.导入Cglib jar包
  • 2.利用Enhancer工具类创建被代理对象(目标对象)的子类对象作为代理对象
  • 3.重写 MethodInterceptor接口的intercept方法,实现对被代理对象的方法的调用
public class Target{
    public void mmethod(){
        System.out.println("目标对象");
    }
}
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 CglibProxy {
    public static void main(String[] args) {
        Target target=new Target();
        Target proxy=(Target) Enhancer.create(target.getClass(), new MethodInterceptor(){
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
              Object obj= method.invoke(target,args);
                return obj;
            }
        });
        proxy.mmethod();//执行代理对象的方法时会触发intercept方法
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值