Когда для proxyBeanMethods следует задать значение false в Springs @Configuration? - PullRequest
0 голосов
/ 17 апреля 2020

При взгляде на автоконфигурацию пружин исходный код кажется, что каждый класс автоконфигурации устанавливает proxyBeanMethods = false.

@Configuration(proxyBeanMethods=false)
public class SomeAutoConfiguration {
    ...
}

Javado c дает подробное объяснение этого конкретного поле:

Укажите, должны ли методы {@code @Bean} передаваться через прокси для обеспечения поведения жизненного цикла компонента, например, для возврата общих экземпляров одноэлементного компонента даже в случае прямого {@code @ Вызов метода Bean} в коде пользователя. (...) Если в этом нет необходимости, поскольку каждый из методов {@code @Bean} этой конкретной конфигурации является автономным и разработан как простой фабричный метод для использования в контейнере, установите этот флаг на {@ code false}, чтобы избежать обработки подкласса CGLIB. (...)

После прочтения этого я все еще растерялся, когда лучше установить false.

Вот мои вопросы:

  • Может ли кто-нибудь привести конкретный пример, когда это поле должно быть истинным, и объяснить, почему?
  • Почему это поле установлено в false на классах автоконфигурации ?

Обновление: Обнаружено две проблемы на github, которые дают некоторое объяснение, почему он равен false в большинстве классов автоконфигурации:

1 Ответ

1 голос
/ 17 апреля 2020

Примерно так:

@Configuration(proxyBeanMethods=true)
public class SomeConfiguration {
    @Bean
    ServiceA serviceA(){
      return new ServiceA(sharedService());
    }

    @Bean
    ServiceB serviceB(){
      return new ServiceB(sharedService());
    }

    @Bean
    ServiceC sharedService(){
      return new ServiceC();
    }
}

Здесь proxyBeanMethods будет гарантировать, что метод sharedService будет перехвачен и его результат будет использован повторно. Если вы будете следовать обычной java logi c, при вызове serviceA () и serviceB () будет два разных экземпляра Service C, а при непосредственном вызове sharedService () будет создан третий экземпляр , Затем прокси-перехватчик удостоверится, что фактический метод вызывается только один раз, поэтому создается только один экземпляр общей службы C, и и ServiceA, и ServiceB получат общий экземпляр.

Вы можете использовать другую конфигурацию паттерны, чтобы избежать этого, что, вероятно, и делают классы автоконфигурации.

Один из способов сделать это - автоматическое подключение сервиса через параметры метода вместо вложенных вызовов методов. В нормальном Java он менее чувствителен, но работает в конфигурациях Spring:

@Configuration(proxyBeanMethods=false)
public class SomeSmarterConfiguration {

    @Bean
    ServiceC sharedService(){
      return new ServiceC();
    }

    @Bean
    ServiceA serviceA(ServiceC sharedService){
      return new ServiceA(sharedService);
    }

    @Bean
    ServiceB serviceB(ServiceC sharedService){
      return new ServiceB(sharedService);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...