當前位置:生活全書館 >

IT科技

> enhancer java

enhancer java

<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://shqsg.com/dianzi/nwkg1x.html