Предотвратить инъекцию бобов с более узкой областью применения с помощью Spring - PullRequest
0 голосов
/ 29 ноября 2018

Я работаю над приложением Spring, используя бины разных областей.Многие бобы синглтоны, другой запрос или пользовательские области.Особенно из-за использования этих пользовательских областей иногда трудно определить, в какую область можно безопасно внедрить, в какую другую область или когда, например, необходимо использовать Provider<T>.

Я знаю, что могу просто создать прокси области действиядля всех бобов, которые в основном не являются синглетонами, но во многих случаях это не кажется необходимым.Например, предполагается, что bean-компонент может быть внедрен в другие bean-объекты той же области, но не все, кто работает над проектом, могут об этом знать.Таким образом, было бы здорово, если бы кто-то мог как-то предотвратить «неправильное использование» этих бинов, особенно если бы не всегда можно было распознать ошибку во времени.

Поэтому мой вопрос: есть ли способ определить, какая область видимости можетбыть безопасно введенным в область действия, а затем предотвратить прямую (без использования Provider<T>) фасоль с более узкой областью действия, например, в синглтон-фасоль?

1 Ответ

0 голосов
/ 30 ноября 2018

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

@Component
public class BeanScopeValidator implements BeanPostProcessor {

  private final ConfigurableListableBeanFactory configurableBeanFactory;

  @Autowired
  public BeanScopeValidator(ConfigurableListableBeanFactory configurableBeanFactory) {
    this.configurableBeanFactory = configurableBeanFactory;
  }

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    String beanScope = configurableBeanFactory.getBeanDefinition(beanName).getScope();
    String[] dependenciesForBean = configurableBeanFactory.getDependenciesForBean(beanName);

    for (String dependencyBeanName : dependenciesForBean) {
      String dependencyBeanScope = configurableBeanFactory.getBeanDefinition(dependencyBeanName).getScope();

      // TODO: Check if the scopes are compatible and throw an exception
    }

    return bean;
  }
}

Этот пример все еще очень прост и не очень удобен в использовании.Наиболее заметно, что в нем отсутствует возможность определения, какая область может быть введена в какую другую область.Таким образом, я создал более полный пример здесь .С помощью этого проекта по умолчанию допускаются следующие инъекции:

  • Синглеты могут быть внедрены во все
  • Все может быть внедрено в прототипы
  • AOP прокси могут быть внедреныво все
  • Все может быть внедрено в bean-объекты одной и той же области видимости

Если вы хотите разрешить инъекцию bean-компонента в другую область видимости, его необходимо явно разрешить с помощьюсоответствующая аннотация:

@Bean
@Scope("prototype")
@InjectableInto("singleton")
MyBean getMyBean(){
  //...
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...