spring怎么用动态代理

worktile 其他 26

回复

共3条回复 我来回复
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    要使用动态代理来使用Spring框架,首先需要了解什么是动态代理。动态代理是一种设计模式,通过在运行时创建和实现接口的代理类来完成方法的拦截和增强。在Spring框架中,动态代理经常用于实现AOP(面向切面编程)功能。

    在Spring中,使用动态代理可以通过两种方式实现:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理
      JDK动态代理是基于接口进行代理的,所以被代理的类必须实现至少一个接口。实现JDK动态代理的步骤如下:

    1.1 创建一个InvocationHandler接口的实现类,该类需要重写invoke方法。在invoke方法中实现业务逻辑的增强。

    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;
        }
    }
    

    1.2 使用Proxy类的newProxyInstance方法创建代理对象。

    public class Main {
        public static void main(String[] args) {
            UserService userService = new UserServiceImpl();
            InvocationHandler handler = new MyInvocationHandler(userService);
            UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
                                                              userService.getClass().getInterfaces(),
                                                              handler);
            proxy.addUser("Tom");
        }
    }
    
    1. CGLIB动态代理
      CGLIB动态代理是通过继承来实现代理的,所以被代理的类不能是final类。实现CGLIB动态代理的步骤如下:

    2.1 创建一个MethodInterceptor接口的实现类,该类需要重写intercept方法。在intercept方法中实现业务逻辑的增强。

    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;
        }
    }
    

    2.2 使用Enhancer类创建代理对象。

    public class Main {
        public static void main(String[] args) {
            UserService userService = new UserServiceImpl();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(userService.getClass());
            enhancer.setCallback(new MyMethodInterceptor());
            UserService proxy = (UserService) enhancer.create();
            proxy.addUser("Tom");
        }
    }
    

    以上是使用动态代理来使用Spring框架的基本步骤。在实际开发中,我们可以将代理逻辑封装成一个通用的类,然后使用Spring的配置文件来配置代理。通过动态代理,我们可以实现日志记录、事务管理等切面功能,提高代码的可维护性和灵活性。

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

    动态代理是Spring框架中非常常用的一种技术,可以在运行时生成代理对象,用于对目标对象进行增强或拦截。在Spring中,有两种常见的动态代理方式:JDK动态代理和CGLIB动态代理。下面是关于Spring如何使用动态代理的步骤和方法:

    1. 接口定义:首先,需要定义一个接口,该接口定义了目标对象的方法。
    public interface UserService {
        void addUser(User user);
        void deleteUser(String userId);
    }
    
    1. 目标对象实现:然后,创建一个类来实现上述接口,并实现其中的方法。
    public class UserServiceImpl implements UserService {
        @Override
        public void addUser(User user) {
            // 添加用户的具体逻辑
        }
        
        @Override
        public void deleteUser(String userId) {
            // 删除用户的具体逻辑
        }
    }
    
    1. 增强逻辑实现:如果需要在目标对象的方法执行前后加入一些额外的逻辑,可以创建一个实现了Advice接口的增强类,并在其中实现相应的前置和后置逻辑。
    public class LogAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            // 在方法执行前执行的逻辑,比如打印日志
            System.out.println("Before method: " + method.getName());
        }
        
        @Override
        public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
            // 在方法执行后执行的逻辑,比如打印日志
            System.out.println("After method: " + method.getName());
        }
    }
    
    1. 创建代理对象:使用Spring框架的ProxyFactoryBean或ProxyFactory类来创建代理对象。ProxyFactoryBean适用于基于接口的代理,而ProxyFactory适用于基于类的代理。
    ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
    proxyFactoryBean.setTarget(new UserServiceImpl()); // 设置目标对象
    proxyFactoryBean.setInterfaces(UserService.class); // 设置代理接口
    proxyFactoryBean.setInterceptorNames("logAdvice"); // 设置增强逻辑
    UserService userService = (UserService) proxyFactoryBean.getObject(); // 创建代理对象
    
    1. 使用代理对象:可以像使用普通的目标对象一样使用代理对象,Spring会自动调用增强逻辑。
    userService.addUser(user); // 调用代理对象的方法
    userService.deleteUser(userId); // 调用代理对象的方法
    

    使用动态代理,可以对目标对象的方法进行拦截、增强、日志记录等操作,而不需要修改目标对象的源代码,提供了更好的灵活性和可扩展性。

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

    Spring框架使用动态代理主要有两种方式:JDK动态代理和CGLIB动态代理。下面分别对这两种方式进行详细的介绍。

    一、JDK动态代理
    JDK动态代理是Java提供的一种动态代理技术,它能够在运行时动态地生成代理类和代理对象。JDK动态代理只能代理接口,不支持代理类。下面是使用JDK动态代理的步骤:

    1. 首先需要定义一个接口,该接口是被代理对象需要实现的接口。例如,定义一个UserService接口:
    public interface UserService {
        void addUser(String username, String password);
        void deleteUser(String username);
        void updateUser(String username, String password);
    }
    
    1. 定义一个实现了InvocationHandler接口的类,该类为代理对象的调用处理器。例如,定义一个UserServiceInvocationHandler类:
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class UserServiceInvocationHandler implements InvocationHandler {
        private Object target; // 被代理的目标对象
    
        public UserServiceInvocationHandler(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;
        }
    }
    
    1. 在Spring配置文件中配置代理对象,并将该代理对象注入到需要使用的地方。例如,配置一个UserService代理对象:
    <bean id="userServiceTarget" class="com.example.UserServiceImpl"/>
    
    <bean id="userServiceProxy" class="java.lang.reflect.Proxy" factory-method="newProxyInstance">
        <constructor-arg value="com.example.UserService"/>
        <constructor-arg>
            <list>
                <value>com.example.UserServiceInvocationHandler</value>
            </list>
        </constructor-arg>
    </bean>
    
    1. 使用代理对象进行方法调用。例如,通过userServiceProxy调用UserService的方法:
    userServiceProxy.addUser("admin", "123456");
    userServiceProxy.deleteUser("admin");
    userServiceProxy.updateUser("admin", "654321");
    

    二、CGLIB动态代理
    CGLIB(Code Generation Library)是一个基于ASM(一个高性能字节码操作库)的代码生成库,它能够在运行时动态地生成代理类和代理对象。相比于JDK动态代理,CGLIB动态代理支持代理类和代理接口。下面是使用CGLIB动态代理的步骤:

    1. 添加CGLIB相关依赖。在项目的pom.xml(Maven项目)或build.gradle(Gradle项目)文件中添加以下依赖:

    Maven:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    

    Gradle:

    compile 'cglib:cglib:3.3.0'
    
    1. 定义一个类作为被代理对象,该类不需要实现接口。例如,定义一个UserServiceImpl类:
    public class UserServiceImpl {
        public void addUser(String username, String password) {
            System.out.println("Add user: " + username);
        }
    
        public void deleteUser(String username) {
            System.out.println("Delete user: " + username);
        }
    
        public void updateUser(String username, String password) {
            System.out.println("Update user: " + username);
        }
    }
    
    1. 定义一个实现了MethodInterceptor接口的类,该类为代理对象的方法拦截器。例如,定义一个UserServiceMethodInterceptor类:
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class UserServiceMethodInterceptor 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;
        }
    }
    
    1. 创建Enhancer对象,并设置被代理类和方法拦截器。例如,创建一个UserService代理对象:
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(UserServiceImpl.class);
    enhancer.setCallback(new UserServiceMethodInterceptor());
    UserServiceImpl userServiceProxy = (UserServiceImpl) enhancer.create();
    
    1. 使用代理对象进行方法调用。例如,通过userServiceProxy调用UserService的方法:
    userServiceProxy.addUser("admin", "123456");
    userServiceProxy.deleteUser("admin");
    userServiceProxy.updateUser("admin", "654321");
    

    以上就是使用Spring框架实现动态代理的方法和操作流程。通过JDK动态代理和CGLIB动态代理,我们可以在不修改原始类的情况下实现对方法的增强和拦截处理。

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

400-800-1024

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

分享本页
返回顶部