網站首頁 學習教育 IT科技 金融知識 旅遊規劃 生活小知識 家鄉美食 養生小知識 健身運動 美容百科 遊戲知識 綜合知識
當前位置:趣知科普吧 > IT科技 > 

enhancer|java

欄目: IT科技 / 發佈於: / 人氣:4.73K

<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);

Tags:enhancer java