Spring的代理如何实现

fiy 其他 15

回复

共3条回复 我来回复
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Spring的代理是通过动态代理机制实现的。在Spring中,主要有两种代理方式:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理:JDK动态代理是基于接口的代理方式。它要求目标对象实现一个接口,并由代理对象实现该接口,通过反射机制来实现方法的调用。JDK动态代理的核心类是Proxy和InvocationHandler。Proxy是生成代理对象的工具类,InvocationHandler是一个接口,用于在代理对象执行方法时进行增强处理。
    • 创建一个实现InvocationHandler接口的代理处理器类,实现invoke()方法,在invoke()方法中可以定义对目标对象方法的增强逻辑。
    • 使用Proxy的newProxyInstance()方法获取代理对象,传入目标对象的类加载器、目标对象的接口、代理处理器对象。
    • 通过代理对象调用方法,实际上是调用代理处理器的invoke()方法,从而实现对目标对象方法的增强逻辑。

    JDK动态代理的优势是实现简单、使用方便,但要求目标对象实现接口。

    1. CGLIB动态代理:CGLIB动态代理是基于类的代理方式。它不要求目标对象实现接口,通过继承目标对象生成代理对象,并重写目标对象的方法,在方法中实现对目标对象方法的增强。

    使用CGLIB动态代理,需引入cglib库,并在Spring配置文件中配置的proxy-target-class属性为true,启用CGLIB动态代理。

    • 引入cglib库,并在Spring配置文件中配置CGLIB代理。
    • 创建一个MethodInterceptor接口的实现类,实现其中的intercept()方法,在intercept()方法中可以定义对目标对象方法的增强逻辑。
    • 通过Enhancer类的create()方法获取代理对象,传入目标对象的类、方法拦截器对象。
    • 通过代理对象调用方法,实际上是调用方法拦截器的intercept()方法,从而实现对目标对象方法的增强逻辑。

    CGLIB动态代理的优势是不要求目标对象实现接口,可以对目标对象的所有方法进行代理,更加灵活。但生成代理对象的过程比较复杂。

    总而言之,Spring的代理是基于动态代理机制实现的,通过Proxy和InvocationHandler或Enhancer和MethodInterceptor实现对目标对象方法的增强处理。通过选择合适的代理方式,可以实现对目标对象的代理增强,从而实现各种功能,如事务管理、性能监控等。

    1年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Spring框架提供了多种代理实现方式,可以根据需求选择合适的方式。

    1. JDK动态代理:
      JDK动态代理是Spring框架默认的代理实现方式,它基于Java的反射机制,在运行时动态地生成代理类。使用JDK动态代理,可以通过接口创建代理对象,并将代理对象用作原始对象的替代品。使用JDK动态代理时,需要使用InvocationHandler接口来定义方法调用的处理逻辑。

    2. CGLIB动态代理:
      CGLIB动态代理是另一种常用的代理实现方式,它通过继承原始对象的方式,生成一个新的子类作为代理类。相比于JDK动态代理,CGLIB动态代理可以代理没有实现接口的类。使用CGLIB动态代理时,需要使用MethodInterceptor接口来定义方法调用的处理逻辑。

    3. 静态代理:
      静态代理是最简单的代理实现方式,它需要手动创建代理类,并将原始对象和代理对象一起编译和部署。在静态代理中,代理对象和原始对象需要实现相同的接口,代理对象在调用原始对象的方法之前或之后执行一些额外的逻辑。

    4. 基于注解的代理实现:
      Spring框架提供了基于注解的代理实现方式,通过在类或方法上添加注解,可以自动地生成代理对象,并进行相关的增强操作。常用的注解包括@Aspect、@Pointcut、@Before、@After等。使用基于注解的代理实现,可以在不修改原始类代码的情况下,实现对原始类的增强。

    5. 异步代理:
      Spring框架还提供了异步代理的功能,通过@Async注解可以将方法标记为异步执行。异步代理会在调用异步方法时,将方法的执行拦截,并将其放入线程池中异步执行,从而提高系统的并发能力和响应性能。

    总结来说,Spring框架的代理实现方式有JDK动态代理、CGLIB动态代理、静态代理和基于注解的代理实现等。根据不同的需求,可以选择适合的方式来实现代理。

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

    Spring的代理是通过AOP(面向切面编程)来实现的。在Spring框架中,可以使用两种方式来实现代理:JDK动态代理和CGLIB动态代理。

    JDK动态代理是通过Java的反射机制来实现的,只能对接口进行代理。而CGLIB动态代理是通过继承的方式来实现的,可以对类进行代理。

    下面分别介绍JDK动态代理和CGLIB动态代理的实现方式和操作流程。

    一、JDK动态代理

    JDK动态代理需要有接口来进行代理,所以首先需要定义一个接口。接口的方法就是代理的方法。

    1. 创建一个接口
    public interface UserService {
        void addUser(String name);
    }
    
    1. 实现接口的类
    public class UserServiceImpl implements UserService {
        @Override
        public void addUser(String name) {
            System.out.println("添加用户:" + name);
        }
    }
    
    1. 创建一个代理类实现InvocationHandler接口
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class UserServiceProxy implements InvocationHandler {
        private Object target;
    
        public UserServiceProxy(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("前置通知");
            Object result = method.invoke(target, args);
            System.out.println("后置通知");
            return result;
        }
    }
    
    1. 创建代理对象
    import java.lang.reflect.Proxy;
    
    public class ProxyDemo {
        public static void main(String[] args) {
            UserService userService = new UserServiceImpl();
            UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
                    userService.getClass().getInterfaces(),
                    new UserServiceProxy(userService));
            proxy.addUser("John");
        }
    }
    

    运行上述代码,将会在控制台上看到如下输出:

    前置通知
    添加用户:John
    后置通知
    

    通过以上步骤,就实现了JDK动态代理。

    二、CGLIB动态代理

    CGLIB动态代理不需要有接口,可以对类进行代理。使用CGLIB动态代理,需要引入CGLIB相关的jar包。

    1. 创建一个类
    public class UserService {
        public void addUser(String name) {
            System.out.println("添加用户:" + name);
        }
    }
    
    1. 创建一个代理类
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    import org.springframework.cglib.proxy.Enhancer;
    
    import java.lang.reflect.Method;
    
    public class UserServiceProxy implements MethodInterceptor {
        private Object target;
    
        public UserServiceProxy(Object target) {
            this.target = target;
        }
    
        public Object getProxyInstance() {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(target.getClass());
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("前置通知");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("后置通知");
            return result;
        }
    }
    
    1. 创建代理对象
    public class ProxyDemo {
        public static void main(String[] args) {
            UserService userService = new UserService();
            UserServiceProxy proxy = new UserServiceProxy(userService);
            UserService userServiceProxy = (UserService) proxy.getProxyInstance();
            userServiceProxy.addUser("John");
        }
    }
    

    运行上述代码,将会在控制台上看到如下输出:

    前置通知
    添加用户:John
    后置通知
    

    通过以上步骤,就实现了CGLIB动态代理。

    总结

    Spring的代理是通过AOP实现的,可以选择JDK动态代理或者CGLIB动态代理来实现代理功能。JDK动态代理适用于有接口的类,而CGLIB动态代理适用于没有接口的类。无论是JDK动态代理还是CGLIB动态代理,都可以在方法执行前后进行一些额外的操作,例如前置通知和后置通知。代理对象可以通过Spring容器来创建,也可以通过代码手动创建。

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

400-800-1024

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

分享本页
返回顶部