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为上面的类生成一个代理:

  这个类是重点,getDaoBean将返回一个代理,  enhancer.setSuperclass(cls);指明了为cls生成代理, enhancer.setCallback(this);指明MyCglibProxy为拦截器,
intercept方法将拦截cls中的方法并作处理。

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;
}

cglib应用的更多相关文章

  1. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  2. cglib动态新增类方法

    <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> & ...

  3. cglib动态代理

    代理即为访问对象添加一层控制层,使其间接化,控制层可以为对象访问添加操作属性. cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许 ...

  4. CGLib动态代理原理及实现

    JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采 ...

  5. java反射 cglib asm相关资料

    有篇文章对java反射的调用的效率做了测试,写的比较好.猛击下面地址 http://www.blogjava.net/stone2083/archive/2010/09/15/332065.html ...

  6. Spring中的cglib动态代理

    Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cg ...

  7. 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】

    一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...

  8. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  9. Java 的静态代理 动态代理(JDK和cglib)

    转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...

  10. Java动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

随机推荐

  1. BZOJ 1316: 树上的询问 (点分治+set)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1316 因为只要求存在某条路径长度为K,所以点分,然后用set判断差值是否在set中就可以了. ...

  2. BZOJ3997: [TJOI2015]组合数学(网络流)

    3997: [TJOI2015]组合数学 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 405  Solved: 284[Submit][Status ...

  3. 在R12下加载Java Bean,配置FORMS_WEB_CONFIG_FILE文件/通过AutoConfig实现Form Server配置文件的修改

    1.定位模版文件$AD_TOP/bin/adtmplreport.sh contextfile=$CONTEXT_FILE target=$FORMS_WEB_CONFIG_FILE以上命令,通过查看 ...

  4. 原生JavaScript常用的DOM操作

    之前项目一直都是用JQuery或者Vue来做的,确实好用,毕竟帮我们解决了很多浏览器兼容问题,但是后面发现大公司面试题都是要原生Javascript来做,然后我就一脸懵逼哈哈哈,毕竟大公司需要的框架或 ...

  5. php备份数据库类分享

    本文实例讲述了php实现MySQL数据库备份类.分享给大家供大家参考.具体分析如下:这是一个非常简单的利用php来备份mysql数据库的类文件,我们只要简单的配置好连接地址用户名与数据库即可   ph ...

  6. mysql 批量更新与批量更新多条记录的不同值实现方法

    作者: 字体:[增加 减小] 类型:转载 时间:2013-10-02 我要评论 在mysql中批量更新我们可能使用update,replace into来操作,下面小编来给各位同学详细介绍mysql ...

  7. git gui提交无法获知你的身份 20

    刚刚学习,请说的详细一些,谢谢 callct | 浏览 3382 次 我有更好的答案 1条回答 你没有定义你的名字和邮箱.你打开git console/shell, #输入下面两句,并且替换成你的名字 ...

  8. Swift2

    Swift 里的数组和字典虽然都是结构体(struct),但在参数传递过程中处理方式却不一样,默认 Array 是引用传递,Dictionary 是值传递.而在 Java 中,由于数组和 Map 都是 ...

  9. springmvc +mybatis 配置多数据源

    1.数据源配置: jdbc_multiple.properties: # MySQL #======================================================== ...

  10. MYSQL问题解决方案:Access denied for user 'root'@'localhost' (using password:YES)

    这两天在MyEclipse中开发Web项目时,连接MYSQL数据库,出现问题:Access denied for user 'root'@'localhost' (using password:YES ...