簡體   English   中英

BeanInfo創建的替代方法?

[英]Alternate method of BeanInfo creation?

我最近將Spring應用程序從Java 1.6移到了Java 1.8。 這導致彈簧自舉花費了一個數量級的時間(之前20s,現在4min)。 追查原因使我進入了為每個bean創建的CachedIntrospectionResults類。 創建后會調用

beanInfo = (shouldIntrospectorIgnoreBeaninfoClasses ?
                        Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO) :
                        Introspector.getBeanInfo(beanClass));

內部檢查器然后在java 1.6中創建bean信息,它調用

 private BeanDescriptor getTargetBeanDescriptor() {
    // Use explicit info, if available,
    if (explicitBeanInfo != null) {
        BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor();
        if (bd != null) {
            return (bd);
        }
    }
    // OK, fabricate a default BeanDescriptor.
    return new BeanDescriptor(this.beanClass);
}

但是在Java 1.8中,它現在會調用

private BeanDescriptor getTargetBeanDescriptor() {
    // Use explicit info, if available,
    if (explicitBeanInfo != null) {
        BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor();
        if (bd != null) {
            return (bd);
        }
    }
    // OK, fabricate a default BeanDescriptor.
    return new BeanDescriptor(this.beanClass, findCustomizerClass(this.beanClass));
}
private static Class<?> findCustomizerClass(Class<?> type) {
    String name = type.getName() + "Customizer";
    try {
        type = ClassFinder.findClass(name, type.getClassLoader());
        // Each customizer should inherit java.awt.Component and implement java.beans.Customizer
        // according to the section 9.3 of JavaBeans&trade; specification
        if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
            return type;
        }
    }
    catch (Exception exception) {
        // ignore any exceptions
    }
    return null;
}

據我所知,此方法是在Java 1.7中添加的,並且由於我未定義任何定制程序類,因此它將搜索我的完整類路徑,然后引發異常,最終需要花費幾百毫秒的時間。 結果是每個bean初始化需要約500ms。 對啟動時間的巨大打擊。

我現在正在嘗試尋找解決此問題的方法,

春天的文檔說要實現BeanInfoFactory以便自定義beanInfo的創建。 但是我找不到任何地方能說明如何為所提供的類創建BeanInfo。

我實際上該怎么做? Introspector使用了一堆私有構造函數來構建它,所以我不能真正遵循它,而簡單地返回一個空BeanInfo就會使它崩潰。 spring實際上想要beaninfo想要什么?

有任何想法嗎?

通常,當您提供顯式BeanInfo ,只要顯式BeanInfo返回null ,Introspector就會自動收集信息。 因此,提供一個僅返回非null BeanDescriptor的空BeanInfo以禁止自動Customizer搜索應該沒有問題。

例如:

import java.beans.*;
import java.util.stream.Stream;

public class BeanInfoTest {
    public static void main(String... arg) throws IntrospectionException {
        BeanInfo bi=Introspector.getBeanInfo(TheComponent.class, Object.class);
        System.out.println("properties: ");
        Stream.of(bi.getPropertyDescriptors())
              .map(p->p.getPropertyType().getSimpleName()+' '+p.getName())
              .forEach(System.out::println);
    }
    public static class TheComponent {
        String foo;
        int bar;
        public String getFoo() {
            return foo;
        }
        public void setFoo(String foo) {
            this.foo = foo;
        }
        public int getBar() {
            return bar;
        }
        public void setBar(int bar) {
            this.bar = bar;
        }
    }
    public static class TheComponentBeanInfo extends SimpleBeanInfo {

        /** Overridden to prevent the automated search for a Customizer */
        @Override
        public BeanDescriptor getBeanDescriptor() {
            System.out.println("Providing my explicit BeanDescriptor");
            return new BeanDescriptor(TheComponent.class);
        }
    }
}

將打印

Providing my explicit BeanDescriptor
properties: 
int bar
String foo

因此,它使用顯式BeanDescriptor時通過自動搜索找到了屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM