簡體   English   中英

Spring - 在配置中使用工廠bean?

[英]Spring - using factory beans in configuration?

@Configuration類中使用工廠bean的正確方法是什么?

假設我有以下SessionFactory

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

現在這個方法返回一個沒有實現SessionFactory的bean工廠。 如果我在另一個使用@Autowired作為SessionFactory bean中使用它,它可以正常工作並從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;
}

實現這種依賴的正確方法是什么?

@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方法之后和返回bean本身之前執行所有必需的初始化。 所以InitializingBeanDisposableBean ,@ @PostConstruct等都被正確識別和處理。 事實上,我總是發現調用afterPropertiesSet有點黑客,因為它是容器的責任。


另外,在Spring數據存儲文檔 - 參考文檔中建議了第二種方法,乍一看看起來有些不一致,但效果很好:

@Resource
private Mongo mongo;

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

因此,工廠是使用@Bean方法創建的,但工廠創建的bean可以使用自動裝配字段獲取。 聰明。

您可以通過以下方式使用它:

@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(...);
  }
}

我在Spring論壇上找到了一個這樣的例子。

@Bean
public SessionFactory sessionFactory() {
    AnnotationSessionFactoryBean sessionFactoryBean = 
              new AnnotationSessionFactoryBean();
    // ...configuration code here...
    sessionFactoryBean.afterPropertiesSet();
    return sessionFactoryBean.getObject();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM