spring boot 2. @Bean 方法在注入@Autowired 依赖之前调用

spring boot 2. @Bean method invoked before injecting @Autowired dependency

这只是好奇。 在下面的示例中,@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。下面的代码片段

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);
    }

}

我的问题是:为什么会这样?

据我所知,有两种方法可以获得 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();


还有你说的好奇的原因

sessionFactory() method is invoked before autowiring EntityManagerFactory and ApplicationContext beans causing NullPointerException

不是这样的

从 Hibernate 5.2 开始,SessionFactory is also an EntityManagerFactory as it now extends said interface. Prior to this the SessionFactory 包装了一个 EntityManagerFactory

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