spring动态代理技术有哪些
-
Spring动态代理技术主要有两种实现方式:JDK动态代理和CGLIB动态代理。
- JDK动态代理
JDK动态代理是通过接口来实现的动态代理,要求被代理的类必须实现至少一个接口。它的核心是利用Java的反射机制在运行时创建一个实现被代理接口的匿名类,并在其中调用被代理方法。JDK动态代理的步骤包括:首先定义一个InvocationHandler接口的实现类,然后通过Proxy类的静态方法newProxyInstance()来创建代理对象。
优点:
- 简单易用,不需要额外的依赖库
- 被代理的类只需要实现接口即可
缺点:
- JDK动态代理只能对实现了接口的类进行代理,无法对没有实现接口的类进行代理
- JDK动态代理只能代理接口中的方法,无法代理类中的方法
- 生成的代理类相对较慢
- CGLIB动态代理
CGLIB动态代理是通过继承被代理类来实现的动态代理,它无需被代理类实现接口。CGLIB动态代理的核心是使用字节码增强库ASM来动态生成被代理类的子类,并在子类中将方法进行拦截和委托。CGLIB动态代理的步骤包括:首先定义一个MethodInterceptor接口的实现类,然后通过Enhancer类的create()方法来创建代理对象。
优点:
- 可以对没有实现接口的类进行代理
- 可以代理类中的方法,包括final方法
缺点:
- 生成的代理类较大,会占用更多的内存空间
- CGLIB动态代理需要引入额外的CGLIB库作为依赖
总结:
JDK动态代理和CGLIB动态代理各有优缺点,选择哪种方式主要根据具体需求来决定。如果被代理类已经实现了接口,且代理的方法主要在接口中,可以选择JDK动态代理;如果被代理类没有实现接口,或者需要代理类中的非接口方法,可以选择CGLIB动态代理。1年前 - JDK动态代理
-
Spring框架提供了多种动态代理技术,以下列举了其中一些常见的技术:
-
JDK动态代理:JDK动态代理是基于接口的代理技术,它使用java.lang.reflect.Proxy类提供的方法来动态生成代理类。代理对象实现了目标接口,在方法调用时会被拦截,可以在方法前后添加额外的处理逻辑。JDK动态代理适用于基于接口的代理场景。
-
CGLIB动态代理:CGLIB动态代理是基于类的代理技术,它通过动态生成子类来实现代理功能。代理对象继承了目标类,可以进行方法的重写和增强,无需目标类实现接口。CGLIB动态代理适用于无接口的代理场景。
-
AspectJ切面编程:AspectJ是一个开源的切面编程框架,它能够在编译时或运行时将切面织入到目标对象的代码中。AspectJ提供了强大的切入点表达式语言,可以精确地指定在目标对象的哪些方法上进行切面织入。在Spring中可以通过引入AspectJ依赖和配置AspectJ注解来实现切面编程。
-
Spring AOP:Spring AOP是Spring框架对AspectJ的封装和实现,它使用动态代理技术在运行时将切面织入到目标对象的方法中。Spring AOP支持基于方法执行的前置、后置、环绕和异常通知等常见切点,可以通过配置和注解的方式实现切面编程。
-
字节码增强工具:除了以上基于代理的动态代理技术,还有一些字节码增强工具可以实现动态代理,例如Byte Buddy和Javassist等。这些工具可以直接修改目标类的字节码来实现代理功能,具有更高的灵活性和性能,但使用起来相对复杂一些。
总之,Spring框架提供了多种动态代理技术来实现切面编程和增强对象功能,开发者可以根据具体的需求选择合适的代理技术。
1年前 -
-
Spring动态代理技术主要有两种实现方式:JDK动态代理和CGLIB动态代理。
一、JDK动态代理
JDK动态代理是通过Java的反射机制来实现的。在Java标准库中,有一个Proxy类和一个InvocationHandler接口,可以用来创建代理对象和实现代理方法的调用。具体的步骤如下:- 定义一个目标对象(被代理对象)和实现InvocationHandler接口的代理对象。
- 在代理对象的invoke方法中,使用反射调用目标对象的方法。
具体的代码示例如下:
public interface HelloService { void sayHello(String name); } public class HelloServiceImpl implements HelloService { public void sayHello(String name) { System.out.println("Hello, " + name); } } 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: " + method.getName()); Object result = method.invoke(target, args); System.out.println("After method: " + method.getName()); return result; } } public class Main { public static void main(String[] args) { HelloService target = new HelloServiceImpl(); MyInvocationHandler handler = new MyInvocationHandler(target); HelloService proxy = (HelloService) Proxy.newProxyInstance(Main.class.getClassLoader(), target.getClass().getInterfaces(), handler); proxy.sayHello("John"); } }运行上述代码,输出结果为:
Before method: sayHello
Hello, John
After method: sayHello二、CGLIB动态代理
CGLIB动态代理是通过继承目标对象的方式来实现的。CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,可以在运行时动态生成指定类的一个子类,并覆盖其中的方法来实现代理。具体的步骤如下:- 引入CGLIB库的依赖。
- 创建一个MethodInterceptor接口的实现类,并在intercept方法中实现代理逻辑。
- 使用Enhancer类来创建代理对象,并将目标对象和MethodInterceptor实现类作为参数传入。
具体的代码示例如下:
// 目标对象 public class HelloService { public void sayHello(String name) { System.out.println("Hello, " + name); } } // MethodInterceptor实现类 public class MyMethodInterceptor 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; } } // 创建代理对象 public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloService.class); enhancer.setCallback(new MyMethodInterceptor()); HelloService proxy = (HelloService) enhancer.create(); proxy.sayHello("John"); } }运行上述代码,输出结果为:
Before method: sayHello
Hello, John
After method: sayHello总结:
- JDK动态代理适用于接口代理,通过Proxy类和InvocationHandler接口实现,利用Java的反射机制来实现代理。
- CGLIB动态代理适用于类代理,通过继承目标对象的方式实现,利用CGLIB生成代理类的子类来覆盖目标方法。
- 在选择使用哪种动态代理技术时,需要根据具体的需求和场景选择合适的方式。
1年前