Cglib基于字节码生成功能(类似于jdk proxy),提供了简单但是强大的动态代理的能力.代码样例基于cglib-2.1.3和asm-1.5.3:
1. Proxy动态代理:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); TestObject orignal = new TestObject(); //基于接口代理 //底层仍基于Enhancer类 TestInterface proxy = (TestInterface)Proxy.newProxyInstance(classLoader, new Class[]{TestInterface.class}, new TestInvocationHandler(orignal)); proxy.testPrint("I am proxy");
static class TestInvocationHandler implements InvocationHandler{ private TestInterface orignal;//被代理类对象, TestInvocationHandler(TestInterface orignal){ this.orignal = orignal; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //around System.out.println("before invoked "); Object result = method.invoke(orignal, args); System.out.println("after invoked"); return result; } } /** * 接口,需要为public * */ public static interface TestInterface{ public void testPrint(String message); } static class TestObject implements TestInterface{ public void testPrint(String message) { System.out.println(message); } }
Cglib的proxy几乎和jdk proxy一样,无论是在api还是设计思路上..二者没有太多的差异性.对于cglib-proxy,底层仍然基于Enhance类做辅助操作(更底层仍然是字节码Generator),仍然是生成Proxy类($Proxy),代理的方式仍然是基于"接口列表"和InvocationHandler.
2. Enhancer动态代理与方法拦截:
//使用TestObject类的默认构造函数,创建代理类实例,此代理类支持"方法拦截" //Enhance不仅支持基于接口列表的方式创建代理类,还支持使用"基类"的方式创建. Callback interceptor = new TestMethodInterceptor(); //底层仍基于Generator来创建代理类(class)且被缓存 TestObject proxy = (TestObject)Enhancer.create(TestObject.class, interceptor); proxy.testMethod();
Callback interceptor = new TestMethodInterceptor(); //指定构造函数,创建代理类实例 Enhancer enhancer = new Enhancer(); enhancer.setCallback(interceptor); enhancer.setSuperclass(TestObject.class); //使用构造函数TestObject(String name) TestObject proxy = (TestObject)enhancer.create(new Class[]{String.class}, new Object[]{"zhangsan"}); proxy.testMethod();
static class TestMethodInterceptor implements MethodInterceptor{ /** * @param obj 代理对象 * @param method 调用的方法,基于jdk reflect,此方法不能直接在当前对象中使用,只能使用在其他实例上,否则将无限循环触发"拦截器" * @param proxy 经过封装的代理类的方法 */ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("here"); //执行当前代理对象的方法 proxy.invokeSuper(obj, args); TestObject other = new TestObject("lisi"); //如下两个方法,不能在当前代理对象中使用. method.invoke(other, args); proxy.invoke(other, args); return null; } }
Enhancer是cglib中用于创建动态代理类的辅助类,它和Proxy类比较起来,不仅能够支持"接口列表"代理,还能支持基于"基类"的代理:
enhancer.setSuperclass(TestObject.class);
Enhancer主要是用来创建"AOP"外观的代理类,它支持了方法拦截特性.
相关推荐
总的来说,CGlib是Java动态代理的重要组成部分,尤其在处理未实现接口的类时,它提供了一种灵活且高效的方法来扩展和拦截代码行为。通过理解并熟练运用CGlib,开发者可以更好地设计和实现复杂的应用场景,如AOP...
2. **CGLIB代理(CGLIB)**:如果目标对象没有实现接口,Spring会使用CGLIB库生成目标对象的子类并进行增强。 **AOP配置** Spring AOP的配置可以通过XML或注解方式进行: 1. **XML配置**:在`<aop:config>`标签下...
最后,本文通过代码样例讲解了AOP的术语和概念: - Aspect切面:通常指一个具有特定关注点的普通类。 - Pointcut切入点:用于指定在哪些类或方法上进行增强操作。 - Advice通知:定义在连接点上执行的动作,分为...
4. **AOP代理**:由于@Cacheable是基于Spring的AOP(面向切面编程)实现的,所以需要确保相关类已经被Spring容器管理,且使用了合适的代理模式(如 JDK动态代理或CGLIB代理)。 5. **异常处理**:当方法抛出异常时...
有两种类型的代理:JDK动态代理和CGLIB代理。JDK代理用于接口,而CGLIB代理用于没有接口或需要更细粒度控制的情况。 在DEMO中,你可能看到如下步骤: 1. 定义一个切面类,包含通知方法。 2. 使用@Aspect注解标记切...
1. **代理模式**:Spring AOP通过两种代理模式实现,即JDK动态代理和CGLIB代理。如果目标类实现了接口,Spring将使用JDK动态代理;否则,使用CGLIB生成目标类的子类。 2. **注解驱动**:Spring AOP支持使用注解来...
Spring Boot默认会为`@Transactional`注解启用CGLIB代理,但如果涉及切面(AspectJ)事务管理,可能需要开启AspectJ的编译时或运行时织入。 6. **代码示例**:在提供的压缩包中,可能包含了一个运行的样例项目,...
7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动...
7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”通知器 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动...
7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”通知器 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动...
7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动...
7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理...