cglib:字节码增强。在运行时,生成目标类的子类,对目标类增强,实现AOP。
应用场景:一般在无接口,只有目标类时使用。
首先确保有如下两个包:
如果项目中,已经使用了Spring,可以忽略导入上述两个包。因为在spring-core中已经集成了上述两个包
假设已有如下目标类:
public class UserServiceImpl { public void addUser() { System.out.println("add user"); } }
在此基础上,不修改源代码,在调用UserServiceImpl的实例方法前后,输出其他的信息。
首先,创建一个切面类MyAspect。
public class MyAspect { public void befor() { System.out.println("befor..."); } public void after() { System.out.println("after..."); } }
再创建一个工厂类,用来获取代理类的实例
import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class MyFactroy { public static UserServiceImpl GetUserService() { // 1 目标类 final UserServiceImpl userService = new UserServiceImpl(); // 2切面类 final MyAspect myAspect = new MyAspect(); // 3.代理类 ,采用cglib,底层创建目标类的子类 // 3.1 核心类 Enhancer enhancer = new Enhancer(); // 3.2 确定父类 enhancer.setSuperclass(userService.getClass()); /* * 3.3 * 使用匿名内部类,重写MethodInterceptor * methodProxy目标方法的代理(暂时不知道干啥用,略) * 方法的代理 */ enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { // 前 myAspect.befor(); // 执行目标类的方法 Object obj = method.invoke(userService, args); // * 执行代理类的父类 ,执行目标类 (目标类和代理类 父子关系) //methodProxy.invokeSuper(proxy, args); // 后 myAspect.after(); return obj; } }); // 3.4 创建代理 UserServiceImpl proxService = (UserServiceImpl) enhancer.create(); return proxService; } }
用junit调用试试看。
import org.junit.Test; public class MyTest { @Test public void test() { UserServiceImpl service = MyFactroy.GetUserService(); service.addUser(); } }
输出结果:
befor... add user after...