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);
以上就是小编今天的分享了,希望可以帮助到大家。