我有基于弹簧的多模块应用程序。在我的DAO模块中,DB(嵌入式derby)由实现ApplicationListener的类启动和创建。
问题是在日志中有来自Spring的巨大堆栈跟踪,它表示没有数据库(无法连接)。
仍然,我的应用程序没有任何问题。此堆栈跟踪在调用ApplicationListener并创建db之前出现。实际上,只有当我第一次在机器上启动应用程序时才会看到它,因为db只创建了这个时间,而不是刚才使用的。
所以我的问题是如何在日志中避免这种异常?也许在应用程序上下文完全加载之前有spring或hibenate设置没有连接到db?或者调用由其他侦听器创建db的代码?
答案 0 :(得分:0)
我想你是从正在创建的spring bean中获取数据库中的一些数据。也许是通过@PostConstruct或其他方式。请记住,在Spring上下文完全加载之前,一些bean可以注入未初始化的bean。
所以不要使用DB,不要调用任何DAO 直到你确定弹簧上下文已完全初始化。
要对DAO进行这样的初始调用,请尝试保证弹簧上下文完整性的模式:
@Component
public class SpringContextMonitor implements ApplicationListener<ApplicationEvent> {
@Autowired
private SomeDao dao;
...
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
onStart((ContextRefreshedEvent) event);
}
}
private void onStart(ContextRefreshedEvent event) {
// do your initialization here
dao.getSomething();
dao2.getSomething();
...
}
...
}
上例中的onStart方法是您确定所有bean都已完全初始化的地方
答案 1 :(得分:0)
这就是我的方式:ROOT上下文包含数据源,dao,服务和事务管理器。在XML配置中,数据库的声明是:
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:url="jdbc:derby:/path/to/database;create=TRUE"
p:username="user" p:password="pwd"
p:driverClassName="org.apache.derby.jdbc.EmbeddedDriver"/>
然后可以使用它来声明hibernate和相关DAO的会话工厂:
<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
id="sessionFactory" p:dataSource-ref="datasource">
<!-- hibernate config -->
...
</bean>
<bean class="org.springframework.orm.hibernate4.HibernateTransactionManager"
name="transactionManager" p:sessionFactory-ref="sessionFactory"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="myDao" class="... .myDaoImpl" p:sessionFactory-ref="sessionFactory" .../>
这样所有都是由spring创建的,这可以确保创建顺序正确。当然,在Java配置中也可以使用相同的逻辑。