2011-12-14 3 views
3

Давайте предположим, что у меня есть аннотированный свойство компонента сеттер, как это:Настраиваемый @Autowired

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; 
    } 
    } 

    ... 

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

Есть ли способ в рамках Springframework достичь чего-то подобного?

ответ

4

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

  • АОПА - плохая идея, вводит накладные расходы во время выполнения перехватывать каждый вызов

  • настраиваемой области - см: Custom spring scopes? Также работает во время выполнения и также плохая идея

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

  • @Configuration - определение фасоли в 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

+1 для @Configuration, все остальные выглядят далеко –

0

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

AnnotationConfigUtils 

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

AutowiredAnnotationBeanPostProcessor 

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

2

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