动态代理

目录

 

代理模式

静态代理

动态代理

AOP中的动态代理

代理模式

给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。

代理模式中代理对象和目标对象要实现相同的接口。

优点:

  1. 控制对目标对象的直接访问,可以很好的隐藏和保护目标对象。
  2. 最重要的一点是,在不改变目标方法的情况下对目标方法进行增强。

静态代理

静态代理就是为每一个需要代理的目标对象都创建一个代理类,程序编译后就存在代理类的class文件。

缺点:目标类和代理类是一对一的关系,当需要多个目标对象需要进行代理的时候,要创建很多的类。代理类也会实现目标类的方法,导致大量代码重复。一个代理类只可以代理一个类型的对象。

动态代理

代理类是在程序运行的时候通过反射机制创建的。可以代理各个类型的对象。

在Java中要想实现动态代理机制,需要java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy类的支持。

动态代理只支持代理接口,不支持代理抽象类。

JDK实现动态代理:使用reflect包中的InvocationHandler(调用处理器)Proxy类来实现。

  • 实现InvocationHandler类的invoke方法。在invoke方法中对目标方法进行增强。invoke(Object proxy(被代理的对象),Method method(方法), Object[] args(方法参数))。
//Object proxy:被代理的对象  
//Method method:要调用的方法  
//Object[] args:方法调用时所需要参数  
public interface InvocationHandler {  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;  
}  
  •  Proxy则利用Inovacation实例来创建代理对象,来间接的调用代理方法。使用newProxyInstance方法(目标类的加载器,目标类的接口,InvocationHandler实例)
//CLassLoader loader:类的加载器  
//Class<?> interfaces:得到全部的接口  
//InvocationHandler h:得到InvocationHandler接口的子类的实例  
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException  

最终的客户端实现:

public static void main(String[] args) {
        //被代理对象
        UserManagerImpl userManager = new UserManagerImpl();
        //Inovacation实例
        LoggerHandler1 loggerHandler1 = new LoggerHandler1(userManager);‘
        //Proxy通过目标对象和Inovacation对象创建代理对象。
        UserManager userManager1 = (UserManager) Proxy.newProxyInstance(userManager.getClass().getClassLoader(),userManager.getClass().getInterfaces(),loggerHandler1);
        userManager1.addUser("1111","张三");
    }

动态代理的应用:日志,事务,拦截器,权限控制等。

AOP中的动态代理

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中剥离出来,改变这些代码的时候并不影响业务逻辑代码,实现解耦。

JDK中的动态代理是基于接口的,没有接口的话是不行的。最后生成的代理类继承了Proxy类,实现了代理的接口。JDK中的动态代理是动态的生成了被目标类的接口的实现类。(代理类实现了被代理的接口,继承了Proxy类)(使用接口)

cglib代理:采用第三方API实现动态代理:动态生成被代理类的子类。(使用继承)

cglib底层运用了asm这个非常强大的Java字节码生成框架来生成class, 比jdk代理效率要高。cglib的代理效率比JDK的动态代理高,但还是建议使用JDK的动态代理,因为第三方的API可能不稳定。

cglib动态代理:

编写被代理对象,被代理对象可以不实现任何接口

创建自己的MethodInterceptor类实现MethodInterceptor的intercep方法。在intercep方法中对代理对象的方法进行增强。

创建enhancer对象,通过enhancer的setSuperClass方法设置代理对象的父类

通过EnHancer的setCallback方法传入自己实现的methodInterceptor对象。

通过create方法创建代理对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值