Весна - использование фабричных бобов в конфигурации? - PullRequest
12 голосов
/ 23 июня 2011

Как правильно использовать фабричные бины в @Configuration классах?

Предположим, у меня есть следующее для SessionFactory:

@Bean
public AnnotationSessionFactoryBean sessionFactory() {
    AnnotationSessionFactoryBean factory = new AnnotationSessionFactoryBean();
    // set up properties etc.
    return factory;
}

Прямо сейчас этот метод возвращает фабрику бинов, которая не реализует SessionFactory. Если я использую его в другом bean-компоненте с @Autowired как SessionFactory, он просто отлично работает и получает его от фабрики bean:

@Controller
public class MyController {
    @Autowired SessionFactory sessionFactory;
    // ...
}

Я думаю, это нормально.

Однако возникает проблема, если я хочу использовать SessionFactory в том же классе конфигурации:

@Bean
public HibernateTransactionManager transactionManager() {
    HibernateTransactionManager man = new HibernateTransactionManager();
    // Ideal - doesn't work because sessionFactory() return type doesn't match:
    // SessionFactory sessionFactory = sessionFactory();
    // Is this one correct?
    // SessionFactory sessionFactory = (SessionFactory) sessionFactory().getObject();
    man.setSessionFactory(sessionFactory);
    return man;
}

Что такое правильный путь для реализации такого рода зависимостей?

Ответы [ 3 ]

21 голосов
/ 23 июня 2011

@Configuration подход все еще относительно свежий и имеет некоторые неровные края. Фабричные бобы являются одним из них. Так что это не Правильный путь , по крайней мере, я не знаю ни о чем. Возможно, будущие релизы Spring как-то справятся с этим делом. На данный момент это мой предпочтительный способ:

@Bean
public AnnotationSessionFactoryBean sessionFactoryBean() {
    AnnotationSessionFactoryBean factory = new AnnotationSessionFactoryBean();
    // set up properties etc.
    return factory;
}

@Bean
public SessionFactory sessionFactory() {
   return (SessionFactory) sessionFactoryBean().getObject();
}

И используйте метод sessionFactory() всякий раз, когда это необходимо. Если по какой-то причине вы хотите вызвать sessionFactoryBean().getObject() несколько раз (например, когда FactoryBean не возвращает синглтоны), не забудьте использовать аннотацию @Scope. В противном случае Spring проверит, что sessionFactory() вызывается только один раз, и кеширует результат.

Spring достаточно умен, чтобы выполнить всю необходимую инициализацию после вызова метода @Bean и перед возвратом самого компонента. Так что InitializingBean, DisposableBean, @PostConstruct и т. Д. Все распознаются и обрабатываются должным образом. На самом деле, я всегда находил вызов afterPropertiesSet чем-то вроде хака, потому что это ответственность контейнера.


Также есть второй метод, рекомендованный в Spring Datastore Document - Справочная документация , который на первый взгляд выглядит немного противоречивым, но прекрасно работает:

@Resource
private Mongo mongo;

@Bean
MongoFactoryBean mongo() {
     return new MongoFactoryBean();
}

Таким образом, фабрика создается с помощью метода @Bean, но созданный фабрикой компонент может быть получен с помощью поля с автопроводкой. Clever.

0 голосов
/ 11 декабря 2015

Вы можете использовать его следующим образом:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class LoginServiceTest {

  @Configuration
  public static class Config {

    @Bean
    public HttpInvokerProxyFactoryBean loginServiceProxy() {
      HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
      proxy.setServiceInterface(LoginService.class);
      proxy.setServiceUrl("http://localhost:8080/loginService");
      return proxy;
    }

  }

  @Inject
  private LoginService loginService;

  @Test
  public void testlogin() {
    loginService.login(...);
  }
}
0 голосов
/ 23 июня 2011

Я нашел пример этого на Весенних форумах .

@Bean
public SessionFactory sessionFactory() {
    AnnotationSessionFactoryBean sessionFactoryBean = 
              new AnnotationSessionFactoryBean();
    // ...configuration code here...
    sessionFactoryBean.afterPropertiesSet();
    return sessionFactoryBean.getObject();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...