spring如何创建代理对象

不及物动词 其他 17

回复

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

    Spring创建代理对象的方式有两种:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理:JDK动态代理是基于接口的代理,它使用Proxy类和InvocationHandler接口来创建代理对象。

      首先,定义一个实现InvocationHandler接口的类,该类中需要实现invoke方法,该方法会在代理对象的方法被调用时被调用。

      其次,通过Proxy类的newProxyInstance方法创建代理对象。该方法接受三个参数:ClassLoader,用于加载代理类;Class[],被代理类的接口列表;InvocationHandler,用于处理代理对象方法调用的逻辑。

      示例代码如下:

      public class MyInvocationHandler implements InvocationHandler {
          private Object target;
      
          public MyInvocationHandler(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              // 增加代理逻辑
              // ...
              Object result = method.invoke(target, args);
              // 增加代理逻辑
              // ...
              return result;
          }
      }
      
      // 创建代理对象
      MyInterface realObject = new MyInterfaceImpl();
      MyInvocationHandler handler = new MyInvocationHandler(realObject);
      MyInterface proxyObject = (MyInterface) Proxy.newProxyInstance(
              realObject.getClass().getClassLoader(),
              realObject.getClass().getInterfaces(),
              handler);
      
    2. CGLIB动态代理:CGLIB动态代理是基于类的代理,它通过继承被代理类并重写其方法来实现代理。

      首先,引入cglib和asm库依赖。

      其次,定义一个实现MethodInterceptor接口的类,该类中需要实现intercept方法,该方法会在代理对象的方法被调用时被调用。在intercept方法中,可以通过MethodProxy来调用原始方法。

      然后,通过Enhancer类的create方法创建代理对象。create方法接受两个参数:Class,被代理类;Callback,用于处理代理对象方法调用的逻辑。

      示例代码如下:

      public class MyMethodInterceptor implements MethodInterceptor {
          @Override
          public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
              // 增加代理逻辑
              // ...
              Object result = proxy.invokeSuper(obj, args);
              // 增加代理逻辑
              // ...
              return result;
          }
      }
      
      // 创建代理对象
      Enhancer enhancer = new Enhancer();
      enhancer.setSuperclass(MyClass.class);
      enhancer.setCallback(new MyMethodInterceptor());
      MyClass proxyObject = (MyClass) enhancer.create();
      

    通过以上两种方式,我们可以使用Spring创建代理对象来实现一些横切逻辑,例如事务管理、日志记录等。根据实际需求选择适合的代理方式。

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

    Spring提供了多种方式来创建代理对象,下面是其中几种常见的方式:

    1. 基于接口的代理:Spring使用JDK动态代理机制来基于接口创建代理对象。当目标对象实现了至少一个接口时,Spring会使用JDK动态代理来创建代理对象。代理对象会实现目标对象所实现的所有接口,并重写接口中的方法,从而实现代理功能。这种方式需要在配置文件中使用aop:config标签进行配置。

    2. 基于类的代理:当目标对象没有实现任何接口时,Spring使用CGLIB代理来创建代理对象。CGLIB是基于字节码的代码生成库,它通过生成目标对象的子类来实现代理功能。代理对象继承目标对象,重写目标对象中的方法,并在方法前后添加增强逻辑。这种方式不需要目标对象实现接口,只需要在配置文件中使用aop:config标签进行配置。

    3. 使用注解方式:Spring提供了基于注解的方式来创建代理对象。通过在目标对象的方法上添加注解,告诉Spring要对该方法进行增强操作。Spring会根据注解的配置自动创建代理对象,并在目标方法执行前后执行增强逻辑。常见的注解方式有@Aspect和@Around等。

    4. 使用编程方式:Spring还提供了编程方式来创建代理对象。通过编写Java代码,手动创建代理对象,并指定代理对象的目标对象、增强逻辑等。这种方式需要在代码中使用ProxyFactory类或者Proxy类来创建代理对象,并进行相关的配置。

    5. 使用模板方式:Spring还提供了模板方式来创建代理对象。通过借助Spring框架中的代理模板类,如JdbcTemplate和RestTemplate等,可以方便地创建代理对象并进行相关操作。这种方式适用于特定的场景,如数据库访问、远程调用等。

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

    Spring框架提供了多种方式来创建代理对象。本文将介绍两种常见的方式:基于接口的代理和基于类的代理。

    一、基于接口的代理
    基于接口的代理是通过JDK动态代理来实现的。JDK动态代理是Java提供的一种动态创建代理对象的机制,需要目标类实现一个或多个接口。

    使用基于接口的代理可以按照以下步骤进行:

    1. 创建目标类的接口
      首先,需要创建一个接口,定义目标类的方法。
    public interface UserService {
        void addUser(User user);
        void deleteUser(User user);
        User getUser(String username);
    }
    
    1. 创建目标类
      然后,创建一个实现了目标类接口的类。
    public class UserServiceImpl implements UserService {
        public void addUser(User user) {
            // 添加用户的逻辑
        }
    
        public void deleteUser(User user) {
            // 删除用户的逻辑
        }
    
        public User getUser(String username) {
            // 获取用户的逻辑
        }
    }
    
    1. 创建代理类
      接下来,创建一个代理类,实现InvocationHandler接口,并重写invoke方法。
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class UserServiceProxy implements InvocationHandler {
        private Object target;
    
        public Object bind(Object target) {
            this.target = target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(), this);
        }
    
        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;
        }
    }
    
    1. 使用代理对象
      最后,可以通过代理类创建代理对象并调用目标方法。
    public class Main {
        public static void main(String[] args) {
            UserService userService = new UserServiceImpl();
            UserService proxy = (UserService) new UserServiceProxy().bind(userService);
            
            proxy.addUser(new User("Alice"));
            proxy.deleteUser(new User("Bob"));
            User user = proxy.getUser("Alice");
        }
    }
    

    二、基于类的代理
    基于类的代理是通过CGLib库来实现的。CGLib是一个强大的,高性能的代码生成库,可以在运行时动态生成目标类的子类。

    使用基于类的代理可以按照以下步骤进行:

    1. 导入CGLib库
      首先,需要在项目中导入CGLib的相关依赖。

    Maven:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    

    Gradle:

    implementation 'cglib:cglib:3.3.0'
    
    1. 创建目标类
      与基于接口的代理不同,不需要创建接口。直接创建目标类即可。
    public class UserService {
        public void addUser(User user) {
            // 添加用户的逻辑
        }
    
        public void deleteUser(User user) {
            // 删除用户的逻辑
        }
    
        public User getUser(String username) {
            // 获取用户的逻辑
        }
    }
    
    1. 创建代理类
      接下来,创建一个代理类,继承MethodInterceptor类,并重写intercept方法。
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class UserServiceProxy implements MethodInterceptor {
        private Object target;
    
        public Object bind(Object target) {
            this.target = target;
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(target.getClass());
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            // 在目标方法执行前的逻辑
            System.out.println("Before method: " + method.getName());
            
            // 执行目标方法
            Object result = proxy.invoke(target, args);
    
            // 在目标方法执行后的逻辑
            System.out.println("After method: " + method.getName());
    
            return result;
        }
    }
    
    1. 使用代理对象
      最后,创建代理对象并调用目标方法。
    public class Main {
        public static void main(String[] args) {
            UserService userService = new UserService();
            UserService proxy = (UserService) new UserServiceProxy().bind(userService);
    
            proxy.addUser(new User("Alice"));
            proxy.deleteUser(new User("Bob"));
            User user = proxy.getUser("Alice");
        }
    }
    

    总结:
    通过以上两种方式,可以创建基于接口或基于类的代理对象。基于接口的代理适用于目标类实现了接口的情况,而基于类的代理适用于目标类没有实现接口的情况。这些代理对象可以在目标方法执行前后添加额外的逻辑,实现对目标方法的拦截和增强。

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

400-800-1024

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

分享本页
返回顶部