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