- CGLIB 动态代理可以代理接口,也可以代理类
- CGLIB 动态代理底层采用继承的方式实现。所以被代理的目标类不能使用final修饰。
-
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
目标类
-
/** * ClassName: UserService * Package: cw.study.spring.service * Description: * 目标类 */ public class UserService { public boolean login(String username, String password) { System.out.println("正在验证身份..."); if ("admin".equals(username) && "123".equals(password)) return true; return false; } public void logout() { System.out.println("退出登录..."); } }
方法拦截器 MethodInterceptor
- 相当于要执行目标方法的时候,会被拦截器拦截,在执行增强代码的过程中执行目标方法,实现对目标方法的增强
-
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * ClassName: TimerMethodInterceptor * Package: client.cw.study.spring.improve * Description: */ public class TimerMethodInterceptor implements MethodInterceptor { /** * 在该方法中编写对目标方法的增强代码 * * @param o 目标对象 * @param method 目标方法 * @param objects 目标方法调用时的实参 * @param methodProxy 代理方法 * @return 目标方法的返回值 * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { // 调用目标前后编写增强代码 long start = System.currentTimeMillis(); // 调用目标对象的方法 // 调用代理对象的父类的方法 Object returnVal = methodProxy.invokeSuper(o, objects); long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - start)); // 返回目标方法的返回值 return returnVal; } }
客户端
-
package client; import client.cw.study.spring.improve.TimerMethodInterceptor; import cw.study.spring.service.UserService; import net.sf.cglib.proxy.Enhancer; /** * ClassName: Client * Package: client * Description: * */ public class Client { public static void main(String[] args) { // 创建字节码增强器对象,CGLIB的核心对象,用于代理类的生成 Enhancer enhancer = new Enhancer(); // 告诉CGLIB代理的目标类,由于CGLIB采用的是继承的方式,所以目标类为代理类的父类 enhancer.setSuperclass(UserService.class); // 设置回调,等同于JDK动态代理的调用处理器 // 在CGLIB中需要实现的接口为MethodInterceptor方法拦截器 enhancer.setCallback(new TimerMethodInterceptor()); // 创建代理对象 // 会在内存中生成目标类的子类,即代理类,然后会创建代理类的对象 UserService userService = (UserService) enhancer.create(); // 使用代理对象的代理方法 System.out.println(userService.login("admin", "123") ? "登录成功" : "登录失败"); userService.logout(); } }
这样就可以完成CGLIB的实现
02-13
2183
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交