这是我参与8月更文挑战的第六天,活动详情查看:8月更文挑战
说到该模块,那么我们得首先了解什么是cglib,它能做什么?OK,我们进行cglib的官网,那么有同学就会问了为什么不百度呢,笔者给的建议是,任何的技能知识、框架语言等不了解时,第一时间应该是去它官网去查阅资料,官方网站更加的权威,版本也是最新的,也会描述近期的规划。去百度或谷歌查阅都是在别人的基础上进行了解,但仅仅是在别人的认知呢,万一别人的错的或者有偏差呢?好,我们继续:点击官网进入
官方的描述:
cglib is a powerful, high performance and quality Code Generation Library. It is used to extend JAVA classes and implements interfaces at runtime. See samples and API documentation to learn more about features.This library is free software, freely reusable for personal or commercial purposes.
大概意思是:cglib是一个强大、高性能、高质量的代价生成库。它用于扩展 JAVA 类并在运行时实现接口。查看示例和API 文档以了解有关功能的更多信息。 该库是免费软件,可自由重复用于个人或商业目的。
不过现在没有怎么更新了,最新的都是2019年。据说stackoverflow讨论中,发现cglib还是有很多的问题,加上github都没有怎么更新了,最新的都是2019年提交记录。建议在实际工作中不要过于依赖,代替方案可以使用Javaassist或者asm框架。
最经典的使用场景就是进行aop处理,OK,cglib介绍就告一段落,我们来看看spring是如何使用它的。
首先声明了AbstractClassGenerator抽象类,该类利用WeakHashMap进行缓存生成的类,它的子类是Enhancer,常用用法
Class<?> configSuperClass;
Enhancer enhancer = new Enhancer();
// configSuperClass 非接口不能声明为final,并且必须有一个可访问的构造函数
enhancer.setSuperclass(configSuperClass);
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
如AbstractAutowireCapableBeanFactory中的autowire方法,实例化指定的bean,底层就是调用了Enhancer
@Override
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
bd.setScope(SCOPE_PROTOTYPE);
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
} else {
Object bean;
if (System.getSecurityManager() != null) {
// instantiate,在这里进行调用
bean = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(bd, null, this),
getAccessControlContext());
}else {
bean = getInstantiationStrategy().instantiate(bd, null, this);
}
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
return bean;
}
}
接着就是MethodProxy类,其作用:当被拦截的方法被调用时,Enhancer 生成的类将此对象传递给注册的MethodInterceptor对象。它可以用来调用原始方法,或者对同一类型的不同对象调用同一方法。以下就是该类被引用的地方