Java-CGLib动态代理

标签: cglib 动态代理
2243人阅读 评论(0) 收藏 举报
分类:

导读

Spring-AOP基础知识

Java-JDK动态代理

Java-CGLib动态代理


问题

另一篇博文中的问题

性能监视横切逻辑代码


CGLib动态代理和JDK动态代理的区别

我们知道使用JDK创建代理时只能为接口创建代理实例。我们从Proxy的newProxyInstance方法中可以看出

    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

第二个参数interfaces就是需要代理实例实现的接口列表。

对于没有通用接口定义业务方法的类,该如何动态创建代理实例呢?
JDK动态代理技术显然无能为力了,CGLib作为一个替代者,很好地解决了这个问题


CGLib概述

CGLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。


改造

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

首先在我们的java maven工程中 添加依赖

    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>${cglib.version}</version>
        </dependency>

使用的版本为 3.2.5

这里写图片描述

package com.xgj.aop.base.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz) {
        // 设置需要创建的子类的类
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        // 通过字节码动态创建子类实例
        return enhancer.create();

    }

    // 拦截父类所有方法的调用
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        // 横切逻辑代码
        PerformanceMonitor.begin(obj.getClass().getName() + "."
                + method.getName());
        // 业务逻辑,通过代理类调用父类中的方法
        Object result = proxy.invokeSuper(obj, args);
        // 横切逻辑代码
        PerformanceMonitor.end();
        return result;
    }

}

上述代码,我们通过getProxy(Class clazz)方法为一个类创建动态代理对象,该代理对象通过扩展clazz实现代理。

在这个代理对象中,织入性能监视的横切逻辑。

public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) 是CGLib定义的Interceptor接口方法,它拦截所有目标类方法中的调用。

其中

  • obj表述目标类的实例

  • method为目标类方法的反射对象

  • args为方法的动态入参

  • proxy为代理类的实例

测试类

通过CglibProxy为ForumSerivceImpl类创建代理对象,并测试代理对象的方法

package com.xgj.aop.base.cglib;

public class ForumServiceTest {

    public static void main(String[] args) {

        CglibProxy cglibProxy = new CglibProxy();
        // 通过动态生成子类的方式创建代理类
        ForumServiceImpl forumService = (ForumServiceImpl) cglibProxy
                .getProxy(ForumServiceImpl.class);
        // 调用代理类的业务方法
        forumService.removeTopic(1);
        forumService.removeForum(2);
    }
}

运行结果

这里写图片描述

通过输出,可以看到除了两个业务方法中都织入了性能监控的逻辑外,还发现代理类的名字变成了

com.xgj.aop.base.cglib.ForumServiceImpl$$EnhancerByCGLIB$$2088954a

这个特殊的类就是CGLib为ForumServiceImpl动态创建的子类。

注意:由于cglib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final或者private方法进行代理

查看评论

java动态代理(重要).

  • 2011年06月24日 22:54
  • 5KB
  • 下载

动态代理——从一窍不通到恍然大悟

从具体的例子出发,由浅入繁介绍代理这种设计模式和具体可以处理的问题
  • u011026779
  • u011026779
  • 2017-04-02 22:50:02
  • 1684

JDK动态代理_JDK动态代理

  • 2009年10月18日 10:56
  • 32KB
  • 下载

动态代理和cglib例子

  • 2017年12月25日 10:27
  • 15KB
  • 下载

动态代理的通俗理解

动态代理 四种类: 1.        被代理类: 以汽车、坦克等为例,这种类有一个抽象接口,例如Moveable,为了在调用实现的具体方法前插入其他的事物逻辑,比如检查车辆情况、检查驾驶员情况...
  • daskyrk
  • daskyrk
  • 2014-08-30 10:25:01
  • 710

动态代理的几种方式

AOP的拦截功能是由java中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执...
  • Happy_wu
  • Happy_wu
  • 2017-12-19 14:34:33
  • 6899

动态代理(2)----动态代理和AOP

根据前面介绍的Proxy和InvocationHandler,实在很难看出这种动态代理的优势,下面介绍一种更实用的动态代理机制.只要我们开发一个实际使用的软件系统,总会出现相同代码重复出现的情形,在这...
  • beijiguangyong
  • beijiguangyong
  • 2013-02-28 22:09:27
  • 4337

动态代理实例

public interface ArithmeticCaculator { int add(int a, int b); int sub(int a, int b); int mul(in...
  • zero_295813128
  • zero_295813128
  • 2016-03-26 18:59:36
  • 701

动态代理实现AOP机制

  • 2011年10月28日 20:24
  • 11.55MB
  • 下载

实现动态代理的两种方式

代理:比如A类需要实现查询功能,就只做查询,而开启事务交由B类处理(相当于某些事情交于其他人帮你做)。 代理类:目标被添加增强代码后,生成的新类就是代理类。 被代理类:目标类,需要被添加增强代码的类。...
  • HLoach
  • HLoach
  • 2017-03-16 10:12:02
  • 730
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 141万+
    积分: 2万+
    排名: 507
    WeChat
      欢迎关注我的公众号,干货只有干货,还有更多惊喜和资源在等着你
    博客专栏