【问题标题】:spring boot 2. @Bean method invoked before injecting @Autowired dependencyspring boot 2.在注入@Autowired依赖之前调用@Bean方法
【发布时间】: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 版本,EntityManagerFactorySessionFactory
  • @M.Deinum 是的,就是这样。我的第二个代码 sn-p 在entityManager.unwrap(SessionFactory.class); 处抛出 NPE,因为我现在正在定义 SessionFactory bean 并且 SessionFactory 扩展了 EntityManagerFactory。这就是在自动装配之前调用 Bean 定义的原因。将您的评论转换为答案,我会将其标记为已接受的答案

标签: spring spring-boot dependency-injection configuration autowired


【解决方案1】:

从 Hibernate 5.2 开始,SessionFactory 也是 EntityManagerFactory,因为它现在扩展了所述接口。在此之前,SessionFactory 包装了 EntityManagerFactory

因此,EntityManagerFactory 无法注入,因为 SessionFactory 是实现该接口的实际 bean。

【讨论】:

    【解决方案2】:

    据我所知,有两种方法可以获取SessionFactory
    来自 EntityManagerFactory

    return entityManagerFactory.unwrap(SessionFactory.class)
    //or -> if you have entitymanager
    return em.getEntityManagerFactory().unwrap(SessionFactory.class);
    

    来自会话

    Session session = entityManager.unwrap(Session.class);
    return session.getSessionFactory();
    


    以及像你说的那样好奇的原因

    在自动装配 EntityManagerFactory 和 ApplicationContext bean 导致 NullPointerException 之前调用 sessionFactory() 方法

    事实并非如此

    【讨论】:

      猜你喜欢
      • 2021-04-24
      • 2018-06-21
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 2019-08-11
      • 2017-06-06
      • 1970-01-01
      • 2020-04-14
      相关资源
      最近更新 更多