Spring源码学习之GCLIB的简单理解
来源:互联网 发布:创客空间的编程 编辑:程序博客网 时间:2024/06/05 06:31
百度百科中对CGLIB的解释是这样的:CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)字节码的动态生成等。不仅如此,它还为spring aop提供了一个底层的实现。
下面就简单写一些代码感受一下gclib的作用:对表格的简单操作。
1.创建一个dao类
public class UserDAO { public void save(){ System.out.println("save() 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 !"); } }这就是一个我们做web开发所熟悉的javaBean,它提供基本的数据库操作:增删改查。
下面我们创建一个Dao工厂,用来生成dao实例:
public class DAOFactory { private static UserDAO userDao = new UserDAO(); public static UserDAO getInstance(){ return userDao; } }创建一个测试类来调用CRUD方法:
public class Test { public static void main(String[] args) { UserDAO userDao = DAOFactory.getInstance(); doMethod(userDao); } public static void doMethod(UserDAO dao){ dao.save(); dao.query(); dao.update(); dao.delete(); } }运行上面的代码,CRUD会被正确的调用,其中并没有涉及cglib。然而变化随之而来,新需求要求这些数据操作功能不能开放给用户,只有“张三”才有权使用,难道我们要在每个方法上面进行判断吗? 显然不可行,Proxy可能是最好的解决办法。但是其中jdk的动态代理需要实现接口,这就要求我们的dao类改变了。既然不想改动dao又要使用代理,只有cglib了。 只需新增一个权限验证的方法拦截器。定义一个拦截器,在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。
public class AuthProxy implements MethodInterceptor { private String name ; //传入用户名称 public AuthProxy(String name){ this.name = name; } public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { //用户进行判断 if(!"张三".equals(name)){ System.out.println("你没有权限!"); return null; } return arg3.invokeSuper(arg0, arg2); } }然后对dao工厂进行修改,提供一个使用代理的实例生成方法:
public static UserDAO getAuthInstance(AuthProxy authProxy){ Enhancer en = new Enhancer(); //进行代理 en.setSuperclass(UserDAO.class); en.setCallback(authProxy); //生成代理实例 return (UserDAO)en.create(); }写一个测试类测试代码运行结果:
public class Test { public static void main(String[] args) { haveAuth(); haveNoAuth(); } public static void haveAuth(){ UserDAO userDao = DAOFactory.getAuthInstance(new AuthProxy("张三")); doMethod(userDao); } public static void haveNoAuth(){ UserDAO userDao = DAOFactory.getAuthInstance(new AuthProxy("李四")); doMethod(userDao); } public static void doMethod(UserDAO dao){ dao.save(); dao.query(); dao.update(); dao.delete(); } }测试结果为:张三正常执行了,李四没有执行。这就是一个简单的aop。
现在除了"张三"其他人都用不了了,现在不可以这样。必须开放查询功能。当然最简单的方式是去修改我们的方法拦截器,不过这样会使逻辑变得复杂,且 不利于维护。还好CGlib给我们提供了方法过滤器(CallbackFilter),CallbackFilte可以明确表明,被代理的类中不同的方法,被哪个拦截器所拦截。下面我们就来做个过滤器用来过滤query方法。
public class AuthProxyFilter implements CallbackFilter{ public int accept(Method arg0) { if(!"query".equalsIgnoreCase(arg0.getName())) return 0; return 1; } }然后在dao工厂中新增一个方法:
public static UserDAO getAuthInstanceByFilter(AuthProxy authProxy){ Enhancer en = new Enhancer(); en.setSuperclass(UserDAO.class); en.setCallbacks(new Callback[]{authProxy,NoOp.INSTANCE}); en.setCallbackFilter(new AuthProxyFilter()); return (UserDAO)en.create(); }程序运行的结果是:张三可以执行CRUD,李四只可以执行查询方法。
0 0
- Spring源码学习之GCLIB的简单理解
- Spring源码学习之简单朴素的理解spring
- Spring 的简单理解
- Spring源码学习之XmlBeanFactory的实现
- opencv源码解析之:CommandLineParser类的简单理解
- opencv源码解析之(5):CommandLineParser类的简单理解
- opencv源码解析之(5):CommandLineParser类的简单理解
- Spring之IOC思想的理解和简单实现
- Spring之IOC思想的理解和简单实现
- 深入理解 Spring 之源码剖析IOC
- Spring学习之源码build
- Spring 源码学习之BeanFactoryAware
- Spring源码学习之AOP
- Spring源码学习之IoC
- Android学习之Activity源码的理解(一)
- 简单描述Spring -- Spring的个人理解
- 学习AOP之透过Spring的Ioc理解Advisor
- 学习AOP之透过Spring的Ioc理解Advisor
- 闭包、作用域和内存
- Java双层for循环输出菱形
- Java求1+1/2!+1/3!+...+1/20!
- 冒泡排序
- 直接选择排序
- Spring源码学习之GCLIB的简单理解
- 反转排序
- 输出数组最小值
- Tomcat源码分析(一)------ 架构
- Java equals与==的区别
- /proc/devices
- 产生6个2到32的随机偶数并求和
- list和set集合的遍历
- Linux cat命令