Настраиваемый @Autowired - PullRequest
       10

Настраиваемый @Autowired

3 голосов
/ 15 декабря 2011

Предположим, у меня есть аннотированный установщик свойства бина, подобный этому:

public class Foo {
  ...
  @Autowired 
  public void setBar(Bar bar) {
    ...
}

Springframework будет искать соответствующее свойство Bar как обычно. Тем не менее, я бы хотел перехватить процесс разрешения бина по умолчанию и добавить немного «магии» сам. Я хотел бы представить такой преобразователь:

public interface SomeResolverInterface<T> {
  public T resolve(Class<T> beanClass);
}

public class BarResolver implements SomeResolverInterface<Bar> {

  @Override
  public Bar resolve(Class<Bar> beanClass) {
    if(someCondition) {
      return someBean;
    } else {
      return anotherBean;
    }
  }

  ...

Я знаю, что мог бы всегда вводить какой-то bean-объект-обертку и перемещать в него разрешающую логику, но я бы предпочел более общий способ использования преобразователя, подобного описанному выше, чтобы сделать Foo полностью независимым от логики разрешения. *

Есть ли в Springframe способ достичь чего-то подобного?

Ответы [ 3 ]

4 голосов
/ 15 декабря 2011

Из вашего описания похоже, что вам нужно только выполнять дополнительную логику во время запуска (автопроводка).Есть несколько способов решения этой проблемы (от наихудшего к лучшему):

  • AOP - плохая идея, вводящая издержки времени выполнения путем перехвата каждого вызова

  • настраиваемая область видимости - см .: Пользовательские области пружины? Также работает во время выполнения и также является плохой идеей

  • @Profile - определить два соответствиябины и включить только один на основе активного профиля.Довольно чистый и вводит накладные расходы только во время запуска

  • @Configuration - определение bean-компонентов в Java дает дополнительное преимущество полного контроля над тем, как они создаются:


@Configuration
public class Config {

    @Autowired
    private Bar someBean;

    @Autowired
    private Bar anotherBean;

    @Bean
    @Primary
    public Bar primaryBean() {
        if(someCondition) {
          return someBean;
        } else {
          return anotherBean;
        }
      }

}

Как вы можете видеть в этом случае, у нас есть три боба типа Bar: someBean, anotherBean и primaryBean.Первые два также можно настроить с помощью @Bean или с помощью компонентного сканирования с помощью @Service.Но чтобы сделать возможным автоматическое подключение, последний primaryBean помечается как @Primary.Таким образом, он будет предпочтительнее двух других.

Это мое рекомендуемое решение, так как логика разрешения понятна, удобна в обслуживании и читаема.ИМХО, это ситуация, когда на основе Java @Configuration действительно сияет.

2 голосов
/ 15 декабря 2011

Помимо опции @Configuration, предоставляемой Tomasz, вы можете использовать простую FactoryBean. Просто реализуйте интерфейс и объявите фабричный бин. В методе getObject() выполните свою собственную логику.

0 голосов
/ 15 декабря 2011

Хотя я никогда не пробовал это, я думаю, вы могли бы посмотреть на подключение вашей логики через

AnnotationConfigUtils

Или посмотрите на

AutowiredAnnotationBeanPostProcessor

и посмотрите, допускает ли это простое расширение / подключение вашей логики

...