spring如何使用cglib

不及物动词 其他 38

回复

共3条回复 我来回复
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    使用CGLIB实现动态代理是Spring框架中常用的方法之一。下面将介绍如何使用Spring框架结合CGLIB库来实现动态代理。

    1. 添加CGLIB依赖

    首先需要在项目中添加CGLIB的依赖。可以通过在pom.xml文件中添加如下依赖来引入CGLIB:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    
    1. 创建目标类

    接下来需要创建一个目标类,即需要被代理的类。例如,我们创建一个名为UserService的类:

    public class UserService {
        public void addUser() {
            System.out.println("Add user");
        }
    }
    
    1. 创建代理类

    然后,创建一个代理类,实现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;
        }
    }
    
    1. 配置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>
    
    1. 使用代理类

    最后,可以通过获取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年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Spring框架通过使用CGLIB库,允许在运行时生成Java类的代理,而不需要实现接口。CGLIB(Code Generation Library)是Java的字节码生成库,可以动态生成子类,实现了方法拦截的功能。

    在Spring中,使用CGLIB生成代理类的方法是通过AopProxy类和ProxyFactoryBean类。

    1. AopProxy:AopProxy是一个接口,有两个实现类:JdkDynamicAopProxy和CglibAopProxy。其中,JdkDynamicAopProxy使用JDK动态代理生成代理类,要求被代理的类必须实现接口;而CglibAopProxy使用CGLIB生成代理类,不需要被代理的类实现接口,会生成被代理类的子类作为代理类。

    2. ProxyFactoryBean:ProxyFactoryBean是一个FactoryBean接口的实现类,用于创建代理对象。它可以配置切点、增强器和代理方式,选择使用JDK动态代理还是CGLIB代理。当配置使用CGLIB代理时,将会使用CglibProxyFactory生成代理类。

    下面是使用Spring框架使用CGLIB生成代理类的步骤:

    1. 引入相关依赖:在项目的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>
    
    1. 配置被代理类和切面类:在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>
    
    1. 配置代理对象工厂:使用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>
    
    1. 获取代理对象:通过从Spring容器中获取代理对象。
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    TargetBean target = (TargetBean) context.getBean("proxyFactoryBean");
    
    1. 调用代理方法:通过代理对象调用目标类的方法,会触发切面类中配置的增强逻辑。
    target.method();
    

    通过以上步骤,就可以在Spring框架中使用CGLIB生成代理类,并实现方法的拦截和增强。在配置文件中,通过设置proxyTargetClass为true,可以选择使用CGLIB代理;如果不设置,默认使用JDK动态代理。使用CGLIB生成的代理类能够拦截非final的类,并且代理方法的性能相对于JDK动态代理更高。

    1年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Spring框架中,可以使用CGLIB库来实现动态代理。CGLIB(Code Generation Library)是一个基于ASM框架的字节码生成库,可以在运行时动态生成代理类。

    CGLIB库可以生成一个被代理类的子类,并重写被代理类中的方法,实现动态代理。与JDK动态代理不同的是,CGLIB动态代理不需要被代理类实现接口,它是通过生成被代理类的子类来实现的。

    下面是使用CGLIB实现动态代理的步骤:

    1. 添加CGLIB库的依赖

    首先,在你的项目中添加CGLIB库的依赖。如果使用Maven,可以在pom.xml文件中添加如下依赖:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.4.0</version>
    </dependency>
    
    1. 定义被代理类

    接下来,需要定义一个被代理类。这个类可以是任意的普通类,不需要实现任何接口。

    public class TargetClass {
        public void doSomething() {
            System.out.println("Original method");
        }
    }
    
    1. 编写代理类

    在这一步,我们需要编写一个代理类来实现对目标类的代理。在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方法中,我们可以在调用目标方法之前和之后执行一些额外的操作。

    1. 创建代理对象

    在使用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年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

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

分享本页
返回顶部