spring代理对象如何产生

回复

共3条回复 我来回复
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Spring代理对象的产生是通过Spring AOP(面向切面编程)和动态代理机制实现的。Spring AOP是Spring框架提供的一种面向切面的编程方式,通过在不修改原有代码的情况下,为目标对象添加额外的功能或剥离部分功能。

    Spring代理对象的产生可以分为两种方式:基于接口的代理和基于类的代理。

    1. 基于接口的代理:
      在目标类有接口的情况下,Spring会使用JDK的动态代理来生成代理对象。JDK动态代理要求目标类实现接口,并且通过反射机制创建代理对象。具体的代理对象生成流程如下:
      (1)Spring先根据目标类和接口信息,创建一个InvocationHandler接口的实现类,该实现类负责处理代理对象的方法调用;
      (2)然后,通过Proxy类的静态方法newProxyInstance()创建代理对象。这个方法需要三个参数:ClassLoader、需要代理的接口数组和InvocationHandler实例;
      (3)最后,通过JVM的提供的字节码增强技术,在运行时动态生成代理对象的类,并创建实例。

    2. 基于类的代理:
      在目标类没有接口的情况下,Spring会使用CGLIB(Code Generation Library,代码生成库)来创建代理对象。CGLIB通过创建目标类的子类来完成代理。具体的代理对象生成流程如下:
      (1)Spring会使用CGLIB创建一个目标类的子类,该子类继承自目标类,并重写其中的方法;
      (2)然后,将代理逻辑添加到子类的重写方法中,以实现代理的功能;
      (3)最后,通过CGLIB创建代理对象,并返回给调用方。

    总结一下,Spring代理对象的产生是通过Spring AOP和动态代理机制实现的。基于接口的代理使用JDK动态代理,基于类的代理使用CGLIB动态代理。

    1年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    Spring代理对象是通过Spring AOP(Aspect-Oriented Programming)实现的。Spring AOP是一种面向切面编程的技术,通过运行时动态地生成代理对象来实现切面功能。

    Spring AOP 在运行时动态地生成代理对象的方式有两种:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理:JDK动态代理是基于接口的代理,通过使用反射机制在运行时动态生成代理类。代理类实现了被代理接口,并在方法调用前后插入切面逻辑。JDK动态代理是通过Java的标准库java.lang.reflect包中的Proxy类和InvocationHandler接口实现的。JDK动态代理只能代理实现了接口的类。

    2. CGLIB动态代理:CGLIB动态代理是基于类的代理,通过继承被代理类来生成代理类。CGLIB动态代理使用了第三方库cglib来生成代理类。CGLIB动态代理可以代理没有实现接口的类。

    Spring使用AOP来实现代理对象的生成。在Spring中,我们可以使用@Aspect注解来定义切面类,使用@Before、@After、@Around等注解来定义切面的具体逻辑。Spring会在运行时根据切面定义生成代理对象,并在方法调用前后插入切面逻辑。可以使用@EnableAspectJAutoProxy注解或者在配置文件中配置,来启用Spring的AOP功能。

    生成代理对象的过程大致如下:

    1. Spring启动时,读取配置文件或使用注解方式配置切面和切点。
    2. Spring根据配置信息,在运行时生成代理对象。如果被代理类实现了接口,则使用JDK动态代理,否则使用CGLIB动态代理。
    3. 当被代理类的方法被调用时,代理对象会拦截方法调用,执行切面逻辑。
    4. 切面逻辑执行完毕后,代理对象会调用被代理对象的方法。

    总结起来,Spring代理对象的生成是通过运行时动态生成代理类来实现的,具体使用JDK动态代理还是CGLIB动态代理取决于被代理类是否实现了接口。使用Spring AOP,我们可以方便地实现切面功能,将横切逻辑和核心业务逻辑分离,提高代码的复用性和可维护性。

    1年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    在Spring框架中,代理对象是通过AOP(面向切面编程)实现的。AOP允许在程序运行期间动态地将代码切入到方法调用的目标方法中,从而实现功能增强。

    Spring框架中,有两种代理方式:JDK动态代理和CGLIB动态代理。下面将分别介绍这两种代理方式的产生过程。

    JDK动态代理

    JDK动态代理是基于接口的代理方式,通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。

    1. 首先,定义一个代理类,实现InvocationHandler接口,并重写invoke()方法,该方法会在目标方法被调用时被触发。

      public class ProxyHandler implements InvocationHandler {
          private Object target; // 目标对象
      
          public ProxyHandler(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              // 在目标方法执行前进行增强操作
              System.out.println("Before method: " + method.getName());
              // 执行目标方法
              Object result = method.invoke(target, args);
              // 在目标方法执行后进行增强操作
              System.out.println("After method: " + method.getName());
              // 返回结果
              return result;
          }
      }
      
    2. 在业务类中,创建一个代理对象,并将目标对象和代理类进行关联。

      // 创建目标对象
      UserService userService = new UserServiceImpl();
      // 创建代理对象
      UserService proxy = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), 
                                     userService.getClass().getInterfaces(), 
                                     new ProxyHandler(userService));
      

      通过Proxy.newProxyInstance()方法来创建代理对象,该方法接受三个参数:ClassLoader,接口数组和InvocationHandler对象。

    3. 使用代理对象进行方法调用。

      proxy.saveUser(user);
      

      代理对象调用方法时,invoke()方法会被触发,从而实现方法的增强。

    CGLIB动态代理

    CGLIB动态代理是基于继承的代理方式,通过net.sf.cglib.proxy.Enhancer类和net.sf.cglib.proxy.MethodInterceptor接口来实现。

    1. 首先,定义一个代理类,实现MethodInterceptor接口,并重写intercept()方法,该方法会在目标方法被调用时被触发。

      public class ProxyInterceptor implements MethodInterceptor {
          @Override
          public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
              // 在目标方法执行前进行增强操作
              System.out.println("Before method: " + method.getName());
              // 执行目标方法
              Object result = proxy.invokeSuper(obj, args);
              // 在目标方法执行后进行增强操作
              System.out.println("After method: " + method.getName());
              // 返回结果
              return result;
          }
      }
      
    2. 在业务类中,创建一个代理对象,并将目标对象和代理类进行关联。

      // 创建目标对象
      UserService userService = new UserServiceImpl();
      // 创建代理对象
      Enhancer enhancer = new Enhancer();
      enhancer.setSuperclass(userService.getClass());
      enhancer.setCallback(new ProxyInterceptor());
      UserService proxy = (UserService) enhancer.create();
      

      使用Enhancer类来创建代理对象,通过setSuperclass()方法设置目标类作为父类,setCallback()方法设置MethodInterceptor实现类作为回调。

    3. 使用代理对象进行方法调用。

      proxy.saveUser(user);
      

      代理对象调用方法时,intercept()方法会被触发,从而实现方法的增强。

    以上是Spring框架中代理对象的产生过程。通过AOP的方式,可以在方法执行前后进行增强操作,如日志记录、事务管理等,从而提供更灵活和可扩展的功能。

    1年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部