spring中aop的动态代理机制有哪些

worktile 其他 7

回复

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

    在Spring中,AOP(Aspect-Oriented Programming)是一种编程范式,用于将与业务逻辑无关的横切关注点从主逻辑中分离出来。在AOP中,动态代理机制是实现横切关注点的一种常见方式。

    Spring中的AOP动态代理机制主要有两种方式:基于接口的JDK动态代理和基于类的CGLIB动态代理。

    1. JDK动态代理:
      JDK动态代理是基于Java的反射机制实现的,它要求目标对象必须实现一个或多个接口。当调用目标对象的方法时,JDK动态代理会通过InvocationHandler接口的invoke()方法拦截方法调用,并在方法调用前后执行额外的逻辑。

    JDK动态代理的使用步骤:

    1. 定义一个类实现InvocationHandler接口,实现invoke()方法,该方法中定义额外逻辑的执行。

    2. 使用Proxy类的newProxyInstance()方法创建代理对象,该方法需要传入ClassLoader、接口数组和InvocationHandler对象。

    3. 调用代理对象的方法,方法调用会被拦截并执行InvocationHandler中定义的逻辑。

    4. CGLIB动态代理:
      CGLIB(Code Generation Library)是一个开源的代码生成库,它通过生成目标类的子类来实现代理。CGLIB动态代理不要求目标对象实现接口,而是直接继承目标类,因此可以代理没有实现接口的类。

    CGLIB动态代理的使用步骤:

    1. 引入CGLIB相关的库。
    2. 定义一个类作为MethodInterceptor,重写intercept()方法,该方法中定义额外逻辑的执行。
    3. 使用Enhancer类的create()方法创建代理对象,该方法需要传入目标类的ClassLoader、目标类的class和MethodInterceptor对象。
    4. 调用代理对象的方法,方法调用会被拦截并执行MethodInterceptor中定义的逻辑。

    需要注意的是,Spring在创建代理对象时会根据情况选择使用JDK动态代理还是CGLIB动态代理。当目标对象实现了接口时,会选择使用JDK动态代理;当目标对象没有实现接口时,会选择使用CGLIB动态代理。

    总结:Spring中的AOP动态代理机制采用了JDK动态代理和CGLIB动态代理两种方式。JDK动态代理要求目标对象实现接口,通过反射实现方法的拦截和增强;CGLIB动态代理则通过生成目标类的子类来实现代理,不要求目标对象实现接口。在使用AOP时,Spring会根据目标对象的类型自动选择使用哪种动态代理方式。

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

    在Spring中,AOP(面向切面编程)通过动态代理机制实现。Spring框架提供了两种动态代理的方式:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理:
      JDK动态代理是基于接口的代理,使用Java反射机制,在运行时动态生成代理类。它要求被代理的目标对象必须实现至少一个接口。JDK动态代理使用InvocationHandler接口和Proxy类进行操作。Spring中的JDK动态代理主要应用在基于接口的AOP方法上。

    2. CGLIB动态代理:
      CGLIB动态代理是基于类的代理,它使用字节码生成库ASM在运行时扩展目标类,并生成一个子类作为代理。CGLIB动态代理不要求目标对象必须实现接口,而是通过生成目标类的子类来实现代理。Spring中的CGLIB动态代理主要应用在没有实现接口的类上。

    3. 生成代理类:
      使用动态代理时,Spring会根据配置文件中的切面信息,在运行时生成代理类。代理类将被添加到目标对象上,在调用目标方法之前或之后执行一些额外的逻辑,在不修改目标类的代码的情况下增强其功能。

    4. 切入点与通知:
      AOP的一个重要概念是切入点和通知。切入点定义了在何处应用通知,而通知指定了在切入点处执行的操作。Spring中的通知类型包括前置通知(在目标方法之前执行)、后置通知(在目标方法之后执行)、环绕通知(在目标方法前后执行)、异常通知(在目标抛出异常时执行)和最终通知(在目标方法执行完毕后执行)。

    5. 配置代理:
      在Spring中配置AOP的代理可以使用XML配置方式或者注解方式。XML配置方式需要定义切面、切入点和通知,并配置在Bean的定义上。注解方式则使用注解来标记切点和通知。无论使用哪种方式配置代理,Spring都会在运行时动态生成代理类并将其织入目标对象中,实现AOP功能。

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

    在Spring中,AOP(面向切面编程)通过动态代理机制来实现,主要有以下两种方式:

    1. JDK动态代理
      JDK动态代理基于接口来进行代理,通过Java中的java.lang.reflect.Proxy类来实现。使用动态代理的前提是被代理类必须实现至少一个接口,代理类通过实现InvocationHandler接口来实现对目标对象的代理控制。

    JDK动态代理使用步骤如下:
    1)定义一个接口,即被代理类实现的接口。
    2)创建一个InvocationHandler接口的实现类,实现代理逻辑。
    3)使用Proxy类的静态方法newProxyInstance()创建代理对象,传入被代理类的ClassLoader、被代理类的接口数组和InvocationHandler对象。
    4)通过代理对象调用方法。

    示例代码如下:

    public interface UserService {
        void addUser();
    }
    
    public class UserServiceImpl implements UserService {
        @Override
        public void addUser() {
            System.out.println("Add user");
        }
    }
    
    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 {
            System.out.println("Before method");
            Object result = method.invoke(target, args);
            System.out.println("After method");
            return result;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            UserService userService = new UserServiceImpl();
            MyInvocationHandler handler = new MyInvocationHandler(userService);
            UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
                    userService.getClass().getInterfaces(),
                    handler);
            proxy.addUser();
        }
    }
    
    1. CGLIB动态代理
      CGLIB(Code Generation Library)动态代理是基于继承的代理方式,通过继承被代理类来创建代理对象,因此不需要被代理类实现接口。CGLIB动态代理使用了更高效的ASM字节码生成框架,性能比JDK动态代理略高。

    CGLIB动态代理使用步骤如下:
    1)引入cglib库。
    2)定义一个类,即被代理类。
    3)创建MethodInterceptor接口的实现类,实现代理逻辑。
    4)通过Enhancer类创建代理对象,设置被代理类和MethodInterceptor对象。
    5)通过代理对象调用方法。

    示例代码如下:

    public class UserService {
        public void addUser() {
            System.out.println("Add user");
        }
    }
    
    public class MyMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("Before method");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("After method");
            return result;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(UserService.class);
            enhancer.setCallback(new MyMethodInterceptor());
    
            UserService proxy = (UserService) enhancer.create();
            proxy.addUser();
        }
    }
    

    无论是JDK动态代理还是CGLIB动态代理,Spring都会根据配置和场景自动选择合适的代理方式来进行AOP操作。

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

400-800-1024

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

分享本页
返回顶部