java enhancer是什么,让我们一起了解一下?
Enhancer是cglib中使用频率很高的一个类,也是一个字节码增强器,可以用来为无接口的类创建代理,功能与java自带的Proxy类相似,会根据某个给定的类创建子类,并且所有非final的方法都带有回调钩子。
了解enhancer之前,我们要知道cglib是什么?
CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
另外,在使用CGLIB代理时需要注意的问题有哪些?
1、如果类是抽象类,只能调用已实现方法方法,如果调用抽象方法的时候会报java.lang.AbstractMethodError。
2、要增强的类不能是final类,否则会报java.lang.IllegalArgumentException: Cannot subclass final class。
3、不能增强类的private方法,否则无法通过编译。
实战操作,enhancer常用的方法示例代码如下:
Enhancer enhancer = new Enhancer();
1、设置要继承的父类
enhancer.setSuperclass(superclass);
2、设置要实现的接口,这里需要实现EnhancedConfiguration,因为EnhancedConfiguration集成了BeanFactoryAware,则要生成对应的实现方法,用于在谁知工厂的时候做增强处理。具体详见ImportAwareBeanPostProcessor。
private static class ImportAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
private final BeanFactory beanFactory;
public ImportAwareBeanPostProcessor(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
// postProcessPropertyValues method attempts to autowire other configuration beans.
if (bean instanceof EnhancedConfiguration) {
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
}
}
enhancer.setInterfaces(new Class>[] {EnhancedConfiguration.class});
3、设置工厂这个还没用
enhancer.setUseFactory(false);
4、作用:指定生成Bean的名字一种策略
public class SpringNamingPolicy extends DefaultNamingPolicy {
public static final SpringNamingPolicy INSTANCE = new SpringNamingPolicy();
@Override
protected String getTag() {
return "BySpringCGLIB";
}
}
例:MathCalculator$$EnhancerBySpringCGLIB$$7e1949802152
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
5、设置用于从该生成器创建字节码的策略。默认情况下使用{@see DefaultGeneratorStrategy}的实例。
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
6、在CGLib回调时可以设置对不同方法执行不同的回调逻辑,或者根本不执行回调 ,具体用法详见:CGLib中CallbackFilter介绍 链接在文章底部
enhancer.setCallbackFilter(CALLBACK_FILTER);
7、设置拦截器的类型
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
8、设置增强器的数组,通过CallbackFilte来指定哪一个方法使用哪一个拦截器,关于Callback的类型具体详见: CGLib中Callback介绍 链接在文章底部
enhancer.setCallbacks(Callback[] callbacks);以上就是小编今天的分享了,希望可以帮助到大家。