最近在看jdk的动态代理和aop的一些概念,发现jdk的动态代理,网上大多写的都很简单,基本都是基于Object类型使用的,导致难以理解, 使用容易出错。按照个人的理解,组织了下jdk动态代理的结构。
util包 : 放置供客户端使用的api
aspect:包放系统中需要的切面实现
经常写JDK动态代理的就可以发现,创建代理对象的过程存在很多相似之处,为此按照个人的理解,提供了以下工具API。
package jdk.util; import java.lang.reflect.InvocationHandler; /** * JDK提供了InvocationHandler用来让使用者自行添加横切逻辑,个人觉得这有2点不好之处:<br> * 1、目标对象和横切逻辑没有关联,实际使用中, 横切逻辑和目标对象的关联,交给了客户端来处理;<br> * 2、InvocationHandler是基于Object,不会在编译期进行类型检查,使用者容易出错;<br> * * 基于这种考虑,提供了接口IProxyCallBack用来约束目标对象和InvocationHandler的关联; * 使用了泛型,是因为一种横切逻辑应该能适用于所有类型的对象; */ // T是需要代理的目标对象的类型 public interface IProxyCallBack<T> extends InvocationHandler { // 返回目标对象 public T getTargetObject(); // 返回回调(感觉好像没有什么用处) public InvocationHandler getInvocationHandler(); }
package jdk.util; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * 1、创建代理对象,对客户端来说应该是一个透明的过程,客户端只需要传递创建中需要的参数即可(目标对象,方法回调);<br> * * 2、创建代理对象是一个重复而且有规律的过程,不管什么类型,只要是创建代理,都应该能使用该方法<br> * * 基于以上2点考虑,提供了工具类方法,用来生成代理对象,客户端只需要传递一个参数即可,使用了泛型,用来支持不同类型的目标对象 */ public final class ProxyFactory { // 返回一个代理类对象,T是目标对象类型 @SuppressWarnings("unchecked") public final static <T> T createProxyInstance(IProxyCallBack<T> callbcak) { T target = callbcak.getTargetObject(); Class<T> targetClazz = (Class<T>) target.getClass(); // jdk只支持基于接口的代理(可以借助cglib实现基于类的代理) if (targetClazz.getInterfaces() == null) { throw new RuntimeException("JDK proxy baseed only interface"); } InvocationHandler hander = callbcak.getInvocationHandler(); Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), hander); return (T) proxy; } }
现在假设有一个已经编写好的服务类和服务接口
package jdk.original; public interface IWelcomeService { public void sayName(); public void sayAge(); } package jdk.original; /** * 已经编写好的服务 */ public class WelcomeServiceImpl implements IWelcomeService { public void sayName() { System.out.println("my name is aty!"); } public void sayAge() { System.out.println("my age is 24"); } }
使用代理的客户端代码如下
import jdk.aspect.LoggerCallbackImpl; import jdk.aspect.TimeCallbackImpl; import jdk.original.IWelcomeService; import jdk.original.WelcomeServiceImpl; import jdk.util.IProxyCallBack; import jdk.util.ProxyFactory; /** * 测试类主要完成2个功能: <br> * 1、创建回调对象(实现横切逻辑、绑定目标对象);<br> * 2、返回生成的代理对象;<br> * * 结合spring的aop,个人理解:<br> * 第1步应该是由使用者实现1个横切面(实现横切逻辑),然后配置该切面需要织入到那些类的哪些方法上(绑定目标对象);<br> * 第2步由框架自动生成代理对象,用户应该感觉不到代理对象的创建;而且用户感觉不到代理对象的使用,<br> * 即用户还是使用原来的目标对象,但是却会加上横切逻辑 */ public class ClientMain { public static void main(String[] args) throws Exception { // 原始对象(织入点) IWelcomeService originalObject = new WelcomeServiceImpl(); // 回调对象(建立横切逻辑和织入点的关联) IProxyCallBack<IWelcomeService> firstHander = new LoggerCallbackImpl<IWelcomeService>( "1级代理", originalObject); // 创建1级代理(框架创建代理对象) IWelcomeService firstProxy = (IWelcomeService) ProxyFactory .createProxyInstance(firstHander); // 客户端透明使用代理 firstProxy.sayName(); System.out.println("-------------------"); // 创建2级代理 IProxyCallBack<IWelcomeService> secondHander = new LoggerCallbackImpl<IWelcomeService>( "2级代理", firstProxy); IWelcomeService secondProxy = (IWelcomeService) ProxyFactory .createProxyInstance(secondHander); secondProxy.sayName(); //添加时间切面 IProxyCallBack<IWelcomeService> timeHander = new TimeCallbackImpl<IWelcomeService>( firstProxy); IWelcomeService timeProxy = (IWelcomeService) ProxyFactory .createProxyInstance(timeHander); timeProxy.sayName(); } }
相关推荐
在Java编程领域,JDK动态代理...Spring AOP则在此基础上提供了更高级的抽象,让我们可以方便地定义和管理切面,从而实现更灵活的代码组织和维护。在实际开发中,两者结合使用可以极大地提高代码的可维护性和可扩展性。
总结来说,Spring AOP基于JDK动态代理的实现,允许我们以非侵入式的方式添加切面逻辑,提高了代码的组织性和模块化。通过理解JDK动态代理的工作原理和Spring AOP的相关概念,我们可以更好地利用这一强大功能,提升...
动态代理和AOP是Java和Spring框架中的重要概念,它们为开发者提供了强大的代码复用和模块化设计的能力。本文将深入解析这两个主题,并结合提供的源码进行详细讲解。 首先,让我们了解一下动态代理。在Java中,动态...
在Java环境中实现AOP时,可以使用Java的动态代理机制。以下是一个简单的示例,展示了如何使用Java反射API实现AOP: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import...
你可能会看到如何通过Spring AOP自定义代理类,以及如何利用JDK动态代理和CGLIB来拦截并增强方法的执行。 3. **第六章_cache-demo.zip**:此示例可能进一步扩展了缓存相关的实现,包括不同类型的缓存策略、缓存更新...
总结来说,Spring的动态代理和AOP是强大的工具,它们允许我们以更优雅的方式编写和组织代码,减少重复,提高代码的可读性和可维护性。通过实例化代理对象和定义切面,我们可以实现诸如日志、事务、安全等横切关注点...
在Java编程领域,AOP(面向切面编程)是一种强大的设计模式,它允许...通过学习这个示例,我们可以更好地理解JDK动态代理的工作原理,以及如何在实际应用中实现AOP的拦截器逻辑,从而提高代码的可维护性和可扩展性。
面向切面编程(AOP)是一种编程范式,主要用于处理...通过学习和实践面向切面编程和动态代理,开发者可以更高效地组织代码,提高代码的可维护性和可扩展性。在Spring框架中,AOP功能的使用让这些目标变得更加容易实现。
- **代理模式**:Spring AOP使用两种代理方式,JDK动态代理和CGLIB代理。如果目标类实现了接口,Spring会使用JDK动态代理;如果没有实现接口,Spring会使用CGLIB代理生成子类。 - **JDK动态代理**:基于接口的代理...
Spring采用动态AOP,其技术基础是代理模式,可以使用JDK动态代理或CGLIB实现。 - **JDK动态代理**:适用于被代理对象实现接口的情况。通过实现InvocationHandler接口并在代理对象调用方法前后插入额外的代码,即切...
AOP允许我们将这些关注点与主业务逻辑分离,从而提高代码的可读性和可维护性。 在Spring框架中,AOP的实现主要依赖于两个核心组件:代理(Proxy)和通知(Advice)。代理是Spring AOP的核心,它在目标对象前创建一...
- **代理(Proxy)**:Spring AOP 通过代理来实现对目标对象的增强,有 JDK 动态代理和 CGLIB 代理两种方式。 2. **AspectJ 1.6.12 Jar 包** `AspectJ` 是一个独立的 AOP 框架,提供了更强大的 AOP 支持,包括...
7. Spring AOP与其他AOP实现(如AspectJ)的比较,了解各自的特点和适用场景。 通过本视频教程的学习,开发者不仅可以掌握Spring AOP的基本使用,还能深入理解面向切面编程的设计思想,从而在实际开发中更加灵活地...
有JDK动态代理和CGLIB代理两种常见的实现方式。 6. **Aspect**:一个完整的切面,包含了切点、通知和任何其他相关配置。 在实践中,Spring AOP是Java开发中最常用的AOP框架之一,它通过注解或XML配置来定义切点和...
Spring AOP与AspectJ是两种实现AOP的方式。AspectJ是一种更全面的AOP实现,它不仅提供了在运行时织入增强的方式,还支持编译期和加载期的织入方式,而Spring AOP是与Spring框架高度集成的,并主要面向企业级应用中...
JDK代理用于实现了接口的目标对象,而CGLIB代理则用于没有接口的类。 6. **引入(Introduction)**:Spring AOP允许在现有类中添加新的方法或属性,这称为类型引入。这可以用于向旧的非AOP类添加新行为,例如添加...
在Java编程领域,Spring框架以...Spring的AOP特性使得我们能够更好地组织代码,将横切关注点与业务逻辑分离,从而提升代码的可重用性和可测试性。在学习和应用这些知识时,结合具体案例进行实践是加深理解的有效途径。
JDK代理用于实现了接口的目标对象,而CGLIB代理用于没有实现接口的类。 10. **织入(Weaving)**: 织入是将切面应用到目标对象并创建代理的过程。Spring支持三种织入方式:编译时织入、类加载时织入和运行时织入。...
8. **AOP代理的理解**:理解Spring是如何通过JDK动态代理或CGLIB代理实现AOP的,这有助于我们了解代理对象是如何在幕后工作的。 9. **实际应用场景**:课程可能还会通过实例讲解AOP在实际项目中的应用,如记录日志...