【发布时间】:2019-04-26 16:29:34
【问题描述】:
这只是好奇。 在下面的示例中,@Autowired EntityManagerFactory 和 @Autowired ApplicationContext 在 @Bean entityManager() 方法之前注入。
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private ApplicationContext context;
@Bean
public EntityManager entityManager() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
return entityManager;
}
}
但是当我将 EntityManager bean 类型更改为 SessionFactory 时,会在自动装配 EntityManagerFactory 和 ApplicationContext bean 之前调用 sessionFactory() 方法,从而在展开 SessionFactory 时导致 NullPointerException。下面代码sn-p
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private ApplicationContext context;
@Bean
public SessionFactory sessionFactory() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
return entityManager.unwrap(SessionFactory.class);
}
}
我的问题是:为什么会这样?
【问题讨论】:
-
我相信你做错了。你能像这样解开会话吗 Session session = unwrap(Session.class);然后获取 session.getSessionFactory();回复
-
感谢您的回复。我不是在问如何正确地做到这一点。我很好奇为什么
@Bean定义在自动装配其他字段之后被调用一次(即@Bean类型是EntityManagerFactory),并且在自动装配其他字段之前被调用一次(即Bean类型是SessionFactory)。我只是想知道这背后的原因,因为我找不到自己的答案 -
我不认为它 (@bean) 在自动装配其他字段之前被调用,因为这将违反 java JVM。因为,在初始化所有数据成员字段之前,JVM 不会让任何方法调用发生。
-
根据您的 Hibernate 版本,
EntityManagerFactory是SessionFactory。 -
@M.Deinum 是的,就是这样。我的第二个代码 sn-p 在
entityManager.unwrap(SessionFactory.class);处抛出 NPE,因为我现在正在定义 SessionFactory bean 并且 SessionFactory 扩展了 EntityManagerFactory。这就是在自动装配之前调用 Bean 定义的原因。将您的评论转换为答案,我会将其标记为已接受的答案
标签: spring spring-boot dependency-injection configuration autowired