![](/img/trans.png)
[英]Spring Hibernate-JPA using Java Based Configuration org.springframework.beans.factory.NoSuchBeanDefinitionException
[英]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本身之前执行所有必需的初始化。 所以InitializingBean
, DisposableBean
,@ @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.