spring中aop的动态代理机制有哪些
-
在Spring中,AOP(Aspect-Oriented Programming)是一种编程范式,用于将与业务逻辑无关的横切关注点从主逻辑中分离出来。在AOP中,动态代理机制是实现横切关注点的一种常见方式。
Spring中的AOP动态代理机制主要有两种方式:基于接口的JDK动态代理和基于类的CGLIB动态代理。
- JDK动态代理:
JDK动态代理是基于Java的反射机制实现的,它要求目标对象必须实现一个或多个接口。当调用目标对象的方法时,JDK动态代理会通过InvocationHandler接口的invoke()方法拦截方法调用,并在方法调用前后执行额外的逻辑。
JDK动态代理的使用步骤:
-
定义一个类实现InvocationHandler接口,实现invoke()方法,该方法中定义额外逻辑的执行。
-
使用Proxy类的newProxyInstance()方法创建代理对象,该方法需要传入ClassLoader、接口数组和InvocationHandler对象。
-
调用代理对象的方法,方法调用会被拦截并执行InvocationHandler中定义的逻辑。
-
CGLIB动态代理:
CGLIB(Code Generation Library)是一个开源的代码生成库,它通过生成目标类的子类来实现代理。CGLIB动态代理不要求目标对象实现接口,而是直接继承目标类,因此可以代理没有实现接口的类。
CGLIB动态代理的使用步骤:
- 引入CGLIB相关的库。
- 定义一个类作为MethodInterceptor,重写intercept()方法,该方法中定义额外逻辑的执行。
- 使用Enhancer类的create()方法创建代理对象,该方法需要传入目标类的ClassLoader、目标类的class和MethodInterceptor对象。
- 调用代理对象的方法,方法调用会被拦截并执行MethodInterceptor中定义的逻辑。
需要注意的是,Spring在创建代理对象时会根据情况选择使用JDK动态代理还是CGLIB动态代理。当目标对象实现了接口时,会选择使用JDK动态代理;当目标对象没有实现接口时,会选择使用CGLIB动态代理。
总结:Spring中的AOP动态代理机制采用了JDK动态代理和CGLIB动态代理两种方式。JDK动态代理要求目标对象实现接口,通过反射实现方法的拦截和增强;CGLIB动态代理则通过生成目标类的子类来实现代理,不要求目标对象实现接口。在使用AOP时,Spring会根据目标对象的类型自动选择使用哪种动态代理方式。
1年前 - JDK动态代理:
-
在Spring中,AOP(面向切面编程)通过动态代理机制实现。Spring框架提供了两种动态代理的方式:JDK动态代理和CGLIB动态代理。
-
JDK动态代理:
JDK动态代理是基于接口的代理,使用Java反射机制,在运行时动态生成代理类。它要求被代理的目标对象必须实现至少一个接口。JDK动态代理使用InvocationHandler接口和Proxy类进行操作。Spring中的JDK动态代理主要应用在基于接口的AOP方法上。 -
CGLIB动态代理:
CGLIB动态代理是基于类的代理,它使用字节码生成库ASM在运行时扩展目标类,并生成一个子类作为代理。CGLIB动态代理不要求目标对象必须实现接口,而是通过生成目标类的子类来实现代理。Spring中的CGLIB动态代理主要应用在没有实现接口的类上。 -
生成代理类:
使用动态代理时,Spring会根据配置文件中的切面信息,在运行时生成代理类。代理类将被添加到目标对象上,在调用目标方法之前或之后执行一些额外的逻辑,在不修改目标类的代码的情况下增强其功能。 -
切入点与通知:
AOP的一个重要概念是切入点和通知。切入点定义了在何处应用通知,而通知指定了在切入点处执行的操作。Spring中的通知类型包括前置通知(在目标方法之前执行)、后置通知(在目标方法之后执行)、环绕通知(在目标方法前后执行)、异常通知(在目标抛出异常时执行)和最终通知(在目标方法执行完毕后执行)。 -
配置代理:
在Spring中配置AOP的代理可以使用XML配置方式或者注解方式。XML配置方式需要定义切面、切入点和通知,并配置在Bean的定义上。注解方式则使用注解来标记切点和通知。无论使用哪种方式配置代理,Spring都会在运行时动态生成代理类并将其织入目标对象中,实现AOP功能。
1年前 -
-
在Spring中,AOP(面向切面编程)通过动态代理机制来实现,主要有以下两种方式:
- 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(); } }- 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年前 - JDK动态代理