【问题标题】:Is it possible to access the HibernateEntityManagerFactory in a custom BeanPostProcessor?是否可以在自定义 BeanPostProcessor 中访问 HibernateEntityManagerFactory?
【发布时间】:2014-08-16 19:05:28
【问题描述】:

在 Spring Boot 应用程序中,我试图从自定义 BeanPostProcessor 中获取 HibernateEntityManagerFactory,例如:

public class HibernateEventListenerBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext;
    private HibernateEntityManagerFactory entityManagerFactory;
    private EventListenerRegistry eventListenerRegistry;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO do the stuff with beans of various types
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.entityManagerFactory = applicationContext.getBean(HibernateEntityManagerFactory.class);
    }
}

但它给了我:

Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.jpa.HibernateEntityManagerFactory] is defined

当我尝试在普通 bean 中自动装配 HibernteEntityManagerFactory 时,它可以正常工作。例如:

@Component
public class HibernateEventListenerRegistrar {

    private HibernateEntityManagerFactory entityManagerFactory;

    @Autowired
    public HibernateEventListenerRegistrar(HibernateEntityManagerFactory entityManagerFactory, List<HibernateEventListener> hibernateEventListeners) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @PostConstruct
    public void registerListeners() {
        // TODO
    }
}

是否可以在 Spring BeanPostProcessor 中访问 HibernateEntityManagerFactory

【问题讨论】:

  • 如果this 有任何帮助。
  • 感谢您的链接,但我不知道它有什么帮助...如果您不这么认为,请告诉我
  • 为什么不把 HibernateEventListenerRegistrar 变成 @Configuration 类而不是 @Component?无需处理 bean 后处理器
  • @geoand 那应该如何工作?我需要用各种类型的豆子做一些事情。这就是为什么我在考虑一个 BeanPostProcessor。同样重要的是,他们要了解订单。
  • 看你的代码,我以为你需要做的事情被HibernateEventListenerRegistrar总结了。由于它是 Spring 配置的一部分,因此您应该使用 @Configuration 而不是 @Component

标签: spring hibernate spring-boot


【解决方案1】:

以下代码将允许您注册 Hibernate 侦听器:

@Configuration
public class HibernateExtraConfig {

    @Autowired
    private HibernateEntityManagerFactory entityManagerFactory;

    @Bean
    public EventListenerRegistry eventListenerRegistry() {
        SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
        return sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
    }
}

@Component
public class HibernateListenersConfigurer {

    private final EventListenerRegistry eventListenerRegistry;
    private final YourListener yourListener;

    @Autowired
    public HibernateListenersConfigurer(EventListenerRegistry eventListenerRegistry,
                                        YourListener yourListener) {

        this.eventListenerRegistry = eventListenerRegistry;
        this.yourListener= yourListener;

        configureListeners();
    }

    private void configureListeners() {
        eventListenerRegistry.getEventListenerGroup(EventType.POST_INSERT).appendListener(yourListenerctListener);
        eventListenerRegistry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(yourListenerctListener);

        //whatever other events you need
    }
}

使用上面的代码,监听器看起来像:

public class YourListener implements PostInsertEventListener, PostUpdateEventListener {

   @Override
   public void onPostInsert(PostInsertEvent event) {

   }

   @Override
   public void onPostUpdate(PostUpdateEvent event) {

   }

   //you might also need this depending on your transaction configuration and what you are trying to do in  the listeners
   @Override
   public boolean requiresPostCommitHanding(EntityPersister persister) {
      return true;
   }

}

【讨论】:

  • 感谢您的回答。问题是我有多个听众,我不希望他们以这种方式自动连接。我正在寻找一种更动态的方法(因此它可能也适用于其他项目)。这就是为什么我想注册任何实现 PostInsertEventListener、PostUpdateEventListener 等的 bean。基于接口我想注册到适当的事件侦听器组。这就是为什么我认为 BeanPostProcessor 将是我的最佳选择。
  • 您可以调整此答案中的代码,使其更具动态性,而不依赖于侦听器的自动装配。它比您的方法更好,因为它不会强制 EntityManagerFactory 的早期实例化(BeanPostProcessors 是特殊的,您应该尽量避免在其初始化程序中对 bean 工厂做任何事情)。
  • 一种解决方案是自动连接 List&lt;PostInsertEventListener&gt; 之类的东西(以及其他相关的听众)并与他们合作
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 2019-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多