Spring的AOP采用了动态代理技术,其中有基于JDK的Proxy的代理和基于CGLIB的代理。
下面介绍一下CGLIB的代理技术。
所谓代理,我的理解就是,如果你想要访问一个类的方法,比如Class Hello类的init()方法,按照普通的操作,我们通常是这样的Hello he = new Hello();he.init(); 这是最直接的访问方式。那么代理就是不直接访问,而是通过代理来访问。CGLIB的代理技术和jdk的还有不同,jdk只能代理接口,而cglib可以代理普通的类。其实cglib是通过底层的字节码技术动态的生成被代理类的一个子类来实现代理的。
下面看一段代码吧,代码也是抄录了一位网友的,嘿嘿。。。。
public class InfoManager {
// 模拟查询操作
public void query() {
System.out.println("query");
}
// 模拟创建操作
public void create() {
System.out.println("create");
}
// 模拟更新操作
public void update() {
System.out.println("update");
}
// 模拟删除操作
public void delete() {
System.out.println("delete");
}
}
这是一个普通的dao类,定义了CRUD的基本操作。
public class InfoManagerFactory {
private static InfoManager manger = new InfoManager();
/**
* 创建原始的InfoManager
*
* @return
*/
public static InfoManager getInstance() {
return manger;
}
}
工厂类,用于产生dao类的实例。其实你不用工厂也没有关系,那就直接new吧。。。。
public class Client {
public static void main(String[] args) {
Client c = new Client();
c.anyonecanManager();
}
/**
* 模拟:没有任何权限要求,任何人都可以操作
*/
public void anyonecanManager() {
System.out.println("any one can do manager");
InfoManager manager = InfoManagerFactory.getInstance();
manager.create();
manager.update();
manager.delete();
manager.query();
}
}
这是主方法,进行一系列的操作。。
这个应用是一个普通的调用,没什么特别的。不过却有一个新的需求,那就是只有一个叫“maurice”的用户登录,才允许对信息进行create,update,delete,query的操作。 拿到这个需求,我们会想到这个干,第一:在InfoManager类中的每个方法里加上一句:if("maurice".equal(username)){},username是作为参数传给方法的。这是个可行的方法。 我们也有第二种方法:那就是在调用方法的时候做总体判断。也是加上那就if。同样可以。
但我们今天要讲的是另外一种方法--代理。新建一个CGLIB代理类:
public class AuthProxy implements MethodInterceptor {
private String name; // 会员登录名
public AuthProxy(String name) {
this.name = name;
}
/**
* 权限校验,如果会员名为:maurice,则有权限做操作,否则提示没有权限
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (!"maurice".equals(this.name)) {
System.out.println("AuthProxy:you have no permits to do manager!");
return null;
}
return proxy.invokeSuper(obj, args);
}
}
这个类继承了MethodInterceptor 类,这是cglib操作必须实现的一个接口。在intercept里我们进行了一个权限的判断,没有权限就返回null,有权限才允许方法通过。这就完成了权限的控制。那么如何使用他呢?
在最开始的factory的代码里,我们可以用这种方法获得目标类的对象InfoManager manager = InfoManagerFactory.getInstance();,如果我们不修改getInstance方法,那就和之前没有任何区别。加入了代理后,我们可以这么写getInstance方法:
public static InfoManager getInstance(AuthProxy auth) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(InfoManager.class);
enhancer.setCallback(auth);
return (InfoManager) enhancer.create();
}
奇迹般的,该方法返回了一个InfoManager对象。其实关键的秘密是enhancer.create()方法,他会去构造InfoManager的一个子类,返回的其实是Infomanager的子类的实例。setCallback()方法比较重要,他有一个参数,这个参数就是你定义的代理类的引用。
所以主方法就可以这么改进:
public class Client {
public static void main(String[] args) {
Client c = new Client();
c.anyonecanManager();
}
/**
* 模拟:没有任何权限要求,任何人都可以操作
*/
public void anyonecanManager() {
System.out.println("any one can do manager");
AuthProxy auth = new AuthProxy("maurice1")
InfoManager manager = InfoManagerFactory.getInstance(auth);
manager.create();
manager.update();
manager.delete();
manager.query();
}
}
这样就实现了权限的控制。。。。。
分享到:
相关推荐
java静态代理 jdk动态代理 cglib动态代理 代理原理
AOP之JDK动态代理和CGLib动态代理 ,具体效果和过程看博文 http://blog.csdn.net/evankaka/article/details/45195383
基于MAVEN项目的CGLib动态代理原理及实现
该资源里面有Jdk动态代理,cglib动态代理,反射和拦截器(链)示例,里面也有所需要的jar包,下载下来导入eclipse即可运行,有问题请问我
代理模式详解-jdk与cglib动态代理与底层实现,spring中常用的设计模式,本案例是从源码到代理模式的实现。
jdk和cglib动态代理的例子{jar包+源码} 解压:如有问题 用快压
cglib实现动态代理,有源代码,详细的实例,逐步分析,实现动态代理。
NULL 博文链接:https://agileshell.iteye.com/blog/1857897
CGlib动态代理类jar包,一共四个jar包,模拟CGlib动态代理用得到。
JDK动态代理必须提供接口才能使用,在一些不能提供接口的环境中,只能采用其他第三方技术,比如CGLIB动态代理,这里提供CGLIB动态代理的相关jar包,供学习和测试使用。
cglib动态代理相关jar包,亲测可用cglib动态代理相关jar包,亲测可用cglib动态代理相关jar包,亲测可用
JAVA动态代理实现Demo(JDK动态代理和CGLIB动态代理)
cglib动态代理用到的两个包 cglib动态代理用到的两个包 cglib动态代理用到的两个包
* Cglib代理(子类代理) * 可以在运行期,扩展java类与实现接口,在内存中创建一个子类对象,实现代理功能 * 底层通过字节码处理框架ASM,转换字节码并生成新的类 * 被代理类都不需要实现接口 * 代理类需要实现...
cglib-nodep-2.1_3.jar、asm-2.2.3.jar、asm-commons-2.2.3.jar、asm-util-2.2.3.jar四个包
cglib动态代理资源包
静态代理、jdk动态代理、cglib动态代理
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)
JDK动态代理和Cglib动态代理实例源码
cglib动态代理技术所需要的Jar包,注意只需要一个jar就可以! cglib-nodep-2.2.2.jar 这个包里面包含了asm的引用,无需在引用!