cglib应用

  JDK的动态代理,经常被用来动态地创建对象的代理。JDK的动态代理用起来非常简单,但是有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口,还可以使用cglib包来完成代理。

  cglib的底层通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的代理类。所以基于cglib开发时需要引入cglib的jar包和ASM的jar包。

下面的例子是基于cglib-2.2.2.jar和asm-all-3.0.jar。

先是一个普通的java类:

package cglib;

public class BookServiceBean {
    public void create() {
        System.out.println("create() is running !");
    }

    public void query() {
        System.out.println("query() is running !");
    }

    public void update() {
        System.out.println("update() is running !");
    }

    public void delete() {
        System.out.println("delete() is running !");
    }
}

  下面的类将基于cglib为上面的类生成一个代理:

package 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 MyCglibProxy implements MethodInterceptor {

    public Enhancer enhancer = new Enhancer();

    private String name;

    public MyCglibProxy(String name) {
        this.name = name;
    }

    public Object getDaoBean(Class cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);
        return result;
    }
}

  写一个简单的工厂:

package cglib;

public class BookServiceFactory {
    private BookServiceFactory() {
    }

    public static BookServiceBean getProxyInstance(MyCglibProxy myProxy){
        return (BookServiceBean)myProxy.getDaoBean(BookServiceBean.class);
    }
}

  写一个模拟的测试:

package cglib;

public class Client {

    public static void main(String [ ] args) {
        BookServiceBean service1 = BookServiceFactory.getProxyInstance(new MyCglibProxy("boss"));
        service1.create();
        BookServiceBean service2 = BookServiceFactory.getProxyInstance(new MyCglibProxy("john"));
        service2.create();
        service2.query();
    }
}

  上面的例子,只是在调用方法前输出一句话,实际意义不大。

  现在希望只有用户名为boss时才有权限调用方法,否则告诉用户权限不够。

将MyCglibProxy修改如下:

package 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 MyCglibProxy implements MethodInterceptor {

    public Enhancer enhancer = new Enhancer();

    private String name;

    public MyCglibProxy(String name) {
        this.name = name;
    }

    public Object getDaoBean(Class cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        //用户进行判断
        if (!"boss".equals(name) ) {
            System.out.println("你没有权限!");
            return null;
        }
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);
        return result;
    }
}

  运行Client发现运行结果已经不同与上次。

  现在是boss和所有的人都有query方法的权限,可以将MyCglibProxy再做修改:

@Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        //用户进行判断
        if (!"boss".equals(name) && !method.getName().equals("query")) {
            System.out.println("你没有权限!");
            return null;
        }
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);
        return result;
    }
时间: 2024-08-27 14:59:57

cglib应用的相关文章

Spring框架_代理模式(静态代理,动态代理,cglib代理)

共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                                      用户库jar包,需要手动发布到tomcat. (每次新建项目) 3) 重新发布项目 * 配置文件错误 (web.xml / struts.xml /bean.xml /hibernate.xml / *.hbm.xml) 明确的提示 * 端口占用 * we

Java进阶之 JDK动态代理与Cglib动态代理

一.动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式[Proxy Pattern]), 动态代理类的字节码是在程序运行时由Java反射机制动态生成. 注意: 1.AspectJ是采用编译时生成AOP代理类,具有更好的性能,但是需要使用特定的编译器进行处理 2.Spring AOP采用运行时生成AOP代理类,无需使用特定编译器进行处理,但是性能相对于AspectJ较差 二.JDK动态代理 [对有实现接口的对象做代理] 1.JDK动态代理中 需要了解的

java动态代理和cglib动态代理

动态代理应用广泛,Spring,Struts等框架很多功能是通过动态代理,或者进一步封装来实现的. 常见的动态代理模式实现有Java API提供的动态代理和第三方开源类库CGLIB动态代理. Java API提供的动态代理是基于类反射实现的,用到的类有: java.lang.reflect.InvocationHandler; java.lang.reflect.Method; java.lang.reflect.Proxy; 其实现是通过Proxy类的newProxyInstance()方法产

JDK动态代理和CGLIB动态代理

转载自http://www.itzhai.com/java-dong-tai-dai-li-zhi-jdk-dong-tai-dai-li-he-cglib-dong-tai-dai-li-mian-xiang-qie-mian-bian-cheng-aop-yuan-li.html 静态代理 静态代理相对来说比较简单,无非就是聚合+多态: 参考:设计模式笔记 – Proxy 代理模式 (Design Pattern) 动态代理 我们知道,通过使用代理,可以在被代理的类的方法的前后添加一些处理方

Cglib动态代理

(1) 首先在项目中加入Cglib的jar包   下载 package com.proxy; 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 StudentProxy <T> implements MethodIn

Spring AOP 实现原理(三) 使用 使用 CGLIB 生成代理类

CGLIB(Code Generation Library),简单来说,就是一个代码生成类库.它可以在运行时候动态是生成某个类的子类. 此处使用前面定义的 Chinese 类,现在改为直接使用 CGLIB 来生成代理,这个代理类同样可以实现 Spring AOP 代理所达到的效果. 下面先为 CGLIB 提供一个拦截器实现类: public class AroundAdvice implements MethodInterceptor { public Object intercept(Obje

谈谈java的代理模式认识 三————CGLIB代理

接着上篇博客的代理模式,我们继续,上篇博客介绍了JDK的动态代理,但是JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,这样就存在一定的局限性.对于这种情况,我们采用CGLIB来实现. 一.CGLIB动态代理 cglib是针对类来实现代理的,其实现原理:CGLIB的底层采用ASM字节码生成框架,使用字节码技术生成代理,比使用反射生成代理的效果要高,是对指定的目标类生成一个子类,并覆盖其中方法实现增强.但是也有一点点不足,因为采用的是继承,所以不能对fina

动态代理方案性能对比 (CGLIB,ASSIT,JDK)

动态代理工具比较成熟的产品有: JDK自带的,ASM,CGLIB(基于ASM包装),JAVAASSIST, 使用的版本分别为: JDK-1.6.0_18-b07, ASM-3.3, CGLIB-2.2, JAVAASSIST-3.11.0.GA (一) 测试结果: 数据为执行三次,每次调用一千万次代理方法的结果,测试代码后面有贴出. (1) PC机测试结果:Linux 2.6.9-42.ELsmp(32bit), 2 Cores CPU(Intel Pentium4 3.06GHz) Java代

Java学习之:JDK动态代理与CGLIB动态代理

代理的概念:简单的理解就是通过为某一个对象创建一个代理对象,我们不直接引用原本的对象,而是由创建的代理对象来控制对原对象的引用. 动态代理:是指在程序运行时由Java反射机制动态生成,无需手动编写代码.动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类. 代理原理:代理对象内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作

cglib初接触

直接上代码吧. pom添加依赖: <dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.ow2.asm</groupId