Пружинная проводка по типу медленнее по величине, чем проводка по названию - PullRequest
24 голосов
/ 24 февраля 2012

В моем проекте я пытаюсь перенести все случаи использования

Foo foo = (Foo) beanFactory.getBean("name");

в

Foo foo = beanFactory.getBean(Foo.class);

Преимущества очевидны: безопасность типов, менее запутанный код, менее бесполезные константы,и т. д. Обычно такие линии располагаются в статических устаревших контекстах, где такая разводка является единственной возможностью.

Все это было хорошо, пока однажды пользователи не стали жаловаться на медлительность, которая, как оказалось, исходила от внутренних компонентов Spring.Так что я запустил профилировщик, чтобы найти точку доступа в

org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)

, которая имеет дорогой вызов

Class.isAssignableFrom(anotherClass).

У меня естьбыстро создал небольшой тест производительности, чтобы выяснить разницу в скорости между поиском по имени строки и типу, это колоссальный 350 раз (я использую StaticApplicationContext для этого теста FAIW)!

Хотяисследуя это, я обнаружил SPR-6870 , который имеет большое количество голосов, но по какой-то причине не рассматривается.Это привело меня к попытке решить эту проблему , которая значительно улучшает ситуацию, но все же медленнее ~ 25 раз, чем поиск по String!Оказывается, эта попытка решает только половину проблемы: она кэширует имя bean-компонента для сохранения на O (n) итерации, но все равно должна сделать вызов isAssignableFrom для проверки типа.

Описанная проблемане только относится к моему сценарию, но также и к bean-компонентам, которые используют @Autowired и могут быть затруднены в случаях, когда bean-компоненты создаются внутри цикла.

Одним из решений будет переопределение одного из методов фабрики bean-компонентови кешировать результаты проверки типа «это бин того же типа», но ясно, что это должно быть сделано в Spring, а не в моем собственном коде.

Кто-то еще страдает от подобной проблемы и обнаружилрешение для этого?

Ответы [ 2 ]

5 голосов
/ 27 мая 2012

Эта проблема теперь решается весной с разрешением SPR-6870 . Подробности смотрите в комментариях к резолюции. Исправление доступно в версиях 3.2.0.RELEASE и 3.1.2.

2 голосов
/ 25 февраля 2012

Большинство приложений Spring связывают вещи во время запуска, а не извлекают компоненты из контекста во время выполнения.Тем не менее, если вы не сильно меняете контекст своего приложения во время обычного запуска своего приложения, вам не следует загружать бин более одного раза.

Учитывая, что, если ваши пользователи жалуются на медлительность, кажется,ваша настоящая проблема - слишком много поисков бобов;использование вами более медленных средств для этого только что выявило реальную проблему.

Я бы попробовал перейти на Java Config (настроить ваши зависимости в Java, как я полагаю, поддерживается в Spring 3.0) и настроить ваше приложение для подключения всехбобы при запуске.Это также имеет то преимущество, что ваше приложение просто не запустится, если не будут найдены зависимости.

...