当前位置:懂科普 >

IT科技

> java enhancer

java enhancer

<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>

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文件格式和指令集都很熟悉。

java enhancer

另外,在使用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);

标签: enhancer java
  • 文章版权属于文章作者所有,转载请注明 https://dongkepu.com/itkeji/p9wmz7.html