gpt4 book ai didi

java - 使用 Hibernate 4's Integrator pattern and Spring' 的依赖注入(inject)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:41:59 25 4
gpt4 key购买 nike

我习惯像这样使用 Spring 进行依赖注入(inject):

<context:component-scan base-package="org.emmerich.myapp" />

然后用 Autowired 注释我的依赖类像这样:

public class DependentClass {

@Autowired
private Dependency dependency;

}

但是,随着 Hibernate 4.0 的变化,我们现在建议使用新的 Integrator服务发现接口(interface)。这包括为触发器添加事件监听器,例如 postUpdate , postDelete等等

不幸的是,这不能很好地通过带注释的依赖项进行依赖注入(inject)。我有以下设置:

我定义的集成器将我的监听器添加到 ServiceFactory .这在文件中引用 META-INF/services/org.hibernate.integrator.spi.Integrator .

public class MyIntegrator implements Integrator {

private MyListener listener;

public MyIntegrator() {
listener = new MyListener();
}

@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventRegistry =
serviceRegistry.getService(EventListenerRegistry.class);

eventRegistry.prependListeners(EventType.POST_COMMIT_INSERT, listener);

}

我还定义了类 MyListener ,它看起来像您的典型事件监听器。

@Component
public class MyListener implements PostInsertEventListener {

@Autowired
private Dependent dependent;

public void onPostInsert(PostInsertEvent event) {
// dependent == null
}

}

不幸的是,如评论所示,这不起作用。我想这是因为我正在实例化 MyListener里面MyIntegrator ,它不会拾取组件,也不会 Autowiring 组件。但是,如果我尝试这样做:

@Component
public class MyIntegrator {

@Autowired
private MyListener listener;

...
}

然后监听器不会 Autowiring 。

首先,使用 Spring 时感觉不对必须做 new MyListener() .我希望能够将其定义为 Autowiring 的依赖项,并让 Spring 为我创建一个单例。我的问题是:

通过新的 Integrator 接口(interface)使用依赖注入(inject)的最佳方法是什么? Integrators 用于构建 SessionFactory,因此当他们被要求集成自己时,我猜没有可用的应用程序上下文。因此,我在 Integrator 中需要的任何 bean 都需要以“老式”方式创建,并且不会在它们上接收 Autowiring 。

我对 Spring 的世界还很陌生,你会说这是我应该期待看到的东西吗?我知道当我在 SessionFactory 中时,我处于不同的应用程序范围内,但是有没有办法获取对 bean 的引用并启用 Autowiring ,即使我是通过 new 创建它的?

我想出的解决方案使用了 ApplicationContextAware .这意味着 MyListener收到了对 ApplicationContext 的引用只要上下文可用,我就会在方法调用时从上下文中引用 bean,而不是在 bean 构造时。使用 new 创建一个 bean不限制这一点,所以 Spring 仍然给我应用程序上下文:

@Component
public class MyListener implements PostInsertEventListener, ApplicationContextAware {

private static ApplicationContext context;

public void onPostInsert(PostInsertEvent event) {
// getDependent() == correct!
}

public void setApplicationContext(ApplicationContext context) throws BeanException {
this.context = context;
}

public Dependent getDependent() {
return context.getBean(Dependent.class);
}

}

有没有更好的办法?

最佳答案

如评论中所述,我采用了另一种集成 Spring 管理的 HibernateEventListeners 的方法。这是代码:

Spring 管理的 Hibernate 事件监听器的标识符接口(interface):

public interface HibernateEventListener { }

HibernateIntegrator:

@Service
public class HibernateSpringIntegrator {

private static final Logger log = LoggerFactory.getLogger(HibernateSpringIntegrator.class);

@Autowired
private HibernateEntityManagerFactory entityManagerFactory;

@Autowired
private HibernateSpringIntegratorRegistry hibernateSpringIntegratorRegistry;

@PostConstruct
public void registerListeners() {
log.debug("Registering Spring managed HibernateEventListeners");

EventListenerRegistry listenerRegistry = ((SessionFactoryImpl) entityManagerFactory
.getSessionFactory()).getServiceRegistry().getService(
EventListenerRegistry.class);
List<HibernateEventListener> eventListeners = hibernateSpringIntegratorRegistry
.getHibernateEventListeners();
for (HibernateEventListener hel : eventListeners) {
log.debug("Registering: {}", hel.getClass());
if (PreInsertEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.PRE_INSERT,
(PreInsertEventListener) hel);
}
if (PreUpdateEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.PRE_UPDATE,
(PreUpdateEventListener) hel);
}
if (PreDeleteEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.PRE_DELETE,
(PreDeleteEventListener) hel);
}
if (PostInsertEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.POST_INSERT,
(PostInsertEventListener) hel);
}
if (PostUpdateEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.POST_UPDATE,
(PostUpdateEventListener) hel);
}
if (PostDeleteEventListener.class.isAssignableFrom(hel.getClass())) {
listenerRegistry.appendListeners(EventType.POST_DELETE,
(PostDeleteEventListener) hel);
}
// Currently we do not need other types of eventListeners. Else this method needs to be extended.
}
}
}

“注册表”:

@Component
public class HibernateSpringIntegratorRegistry {

@Autowired(required = false)
private List<HibernateEventListener> hibernateEventListeners;

public List<HibernateEventListener> getHibernateEventListeners() {
if (hibernateEventListeners == null) {
return Collections.emptyList();
}
return hibernateEventListeners;
}
}

这是一个示例实现:

@Component
public class MailGenerationEventListener implements HibernateEventListener,
PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener {

@Override
public void onPostDelete(PostDeleteEvent event) {
Class<?> entityClass = event.getEntity().getClass();
...
}

@Override
public void onPostInsert(PostInsertEvent event) {
Class<?> entityClass = event.getEntity().getClass();
...
}

@Override
public void onPostUpdate(PostUpdateEvent event) {
Class<?> entityClass = event.getEntity().getClass();
...
}
}

关于java - 使用 Hibernate 4's Integrator pattern and Spring' 的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16019820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com