spring如何使用cglib
-
使用CGLIB实现动态代理是Spring框架中常用的方法之一。下面将介绍如何使用Spring框架结合CGLIB库来实现动态代理。
- 添加CGLIB依赖
首先需要在项目中添加CGLIB的依赖。可以通过在pom.xml文件中添加如下依赖来引入CGLIB:
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>- 创建目标类
接下来需要创建一个目标类,即需要被代理的类。例如,我们创建一个名为UserService的类:
public class UserService { public void addUser() { System.out.println("Add user"); } }- 创建代理类
然后,创建一个代理类,实现MethodInterceptor接口,并重写它的intercept()方法,该方法会在目标方法执行前后进行拦截。在拦截方法中,可以添加额外的逻辑。
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class UserServiceProxy implements MethodInterceptor { private Object target; public UserServiceProxy(Object target) { this.target = target; } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method: " + method.getName()); Object result = method.invoke(target, args); System.out.println("After method: " + method.getName()); return result; } }- 配置Spring Bean
接下来,在Spring的配置文件(如applicationContext.xml)中配置Bean。在配置中,将目标类和代理类进行关联。
<bean id="userService" class="com.example.UserService"/> <bean id="userServiceProxy" class="com.example.UserServiceProxy"> <constructor-arg name="target" ref="userService"/> </bean>- 使用代理类
最后,可以通过获取Spring容器中的代理类实例来使用代理类:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserServiceProxy userServiceProxy = (UserServiceProxy) context.getBean("userServiceProxy"); userServiceProxy.addUser(); } }运行以上代码,会输出以下结果:
Before method: addUser Add user After method: addUser可以看到,代理类成功拦截了目标方法的执行,并在方法执行前后加入了额外的逻辑。
以上是使用Spring框架结合CGLIB实现动态代理的步骤和示例代码。希望对你有帮助!
1年前 -
Spring框架通过使用CGLIB库,允许在运行时生成Java类的代理,而不需要实现接口。CGLIB(Code Generation Library)是Java的字节码生成库,可以动态生成子类,实现了方法拦截的功能。
在Spring中,使用CGLIB生成代理类的方法是通过AopProxy类和ProxyFactoryBean类。
-
AopProxy:AopProxy是一个接口,有两个实现类:JdkDynamicAopProxy和CglibAopProxy。其中,JdkDynamicAopProxy使用JDK动态代理生成代理类,要求被代理的类必须实现接口;而CglibAopProxy使用CGLIB生成代理类,不需要被代理的类实现接口,会生成被代理类的子类作为代理类。
-
ProxyFactoryBean:ProxyFactoryBean是一个FactoryBean接口的实现类,用于创建代理对象。它可以配置切点、增强器和代理方式,选择使用JDK动态代理还是CGLIB代理。当配置使用CGLIB代理时,将会使用CglibProxyFactory生成代理类。
下面是使用Spring框架使用CGLIB生成代理类的步骤:
- 引入相关依赖:在项目的pom.xml文件中,引入spring-aop和cglib依赖。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>- 配置被代理类和切面类:在Spring配置文件中,配置被代理的目标类和切面类。切面类包含了前置通知、后置通知、环绕通知等增强逻辑。
<bean id="targetBean" class="com.example.TargetBean" /> <bean id="aspectBean" class="com.example.AspectBean" /> <aop:config> <aop:aspect ref="aspectBean"> <aop:pointcut expression="execution(* com.example.TargetBean.*(..))" id="targetMethods" /> <aop:before method="beforeAdvice" pointcut-ref="targetMethods" /> <aop:after method="afterAdvice" pointcut-ref="targetMethods" /> </aop:aspect> </aop:config>- 配置代理对象工厂:使用ProxyFactoryBean配置代理对象工厂,设置目标类和切面类,选择使用CGLIB代理。
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="targetBean" /> <property name="interceptorNames"> <list> <value>aspectBean</value> </list> </property> <property name="proxyTargetClass" value="true" /> </bean>- 获取代理对象:通过从Spring容器中获取代理对象。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); TargetBean target = (TargetBean) context.getBean("proxyFactoryBean");- 调用代理方法:通过代理对象调用目标类的方法,会触发切面类中配置的增强逻辑。
target.method();通过以上步骤,就可以在Spring框架中使用CGLIB生成代理类,并实现方法的拦截和增强。在配置文件中,通过设置proxyTargetClass为true,可以选择使用CGLIB代理;如果不设置,默认使用JDK动态代理。使用CGLIB生成的代理类能够拦截非final的类,并且代理方法的性能相对于JDK动态代理更高。
1年前 -
-
Spring框架中,可以使用CGLIB库来实现动态代理。CGLIB(Code Generation Library)是一个基于ASM框架的字节码生成库,可以在运行时动态生成代理类。
CGLIB库可以生成一个被代理类的子类,并重写被代理类中的方法,实现动态代理。与JDK动态代理不同的是,CGLIB动态代理不需要被代理类实现接口,它是通过生成被代理类的子类来实现的。
下面是使用CGLIB实现动态代理的步骤:
- 添加CGLIB库的依赖
首先,在你的项目中添加CGLIB库的依赖。如果使用Maven,可以在pom.xml文件中添加如下依赖:
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.4.0</version> </dependency>- 定义被代理类
接下来,需要定义一个被代理类。这个类可以是任意的普通类,不需要实现任何接口。
public class TargetClass { public void doSomething() { System.out.println("Original method"); } }- 编写代理类
在这一步,我们需要编写一个代理类来实现对目标类的代理。在CGLIB中,代理类是目标类的子类。
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class ProxyClass implements MethodInterceptor { private Object targetObject; public ProxyClass(Object targetObject) { this.targetObject = targetObject; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method"); Object result = proxy.invoke(targetObject, args); System.out.println("After method"); return result; } }在上述代码中,
ProxyClass类实现了MethodInterceptor接口,并重写了intercept方法。在intercept方法中,我们可以在调用目标方法之前和之后执行一些额外的操作。- 创建代理对象
在使用CGLIB生成代理对象之前,我们需要先创建一个Enhancer对象,并设置被代理类和代理类。
import net.sf.cglib.proxy.Enhancer; public class Main { public static void main(String[] args) { TargetClass target = new TargetClass(); ProxyClass proxy = new ProxyClass(target); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(TargetClass.class); enhancer.setCallback(proxy); TargetClass proxyObject = (TargetClass) enhancer.create(); proxyObject.doSomething(); } }在上面的代码中,我们创建了一个Enhancer对象,并将其设置为被代理类
TargetClass的父类。然后,我们将ProxyClass对象设置为回调类。最后,我们使用Enhancer对象的
create方法来创建代理对象。返回的代理对象可以调用被代理类的方法,在调用被代理类的方法前后,会执行ProxyClass中的intercept方法。当执行
proxyObject.doSomething()方法时,会输出以下结果:Before method Original method After method上述示例演示了如何使用CGLIB库来实现动态代理。Spring框架中也可以通过AOP(面向切面编程)来使用CGLIB进行动态代理。可以使用
@EnableAspectJAutoProxy(proxyTargetClass=true)启用CGLIB代理。1年前