我习惯于使用 Spring 来进行依赖注入,如下所示:
<context:component-scan base-package="org.emmerich.myapp" />
然后Autowired
像这样注释我的依赖类:
public class DependentClass {
@Autowired
private Dependency dependency;
}
然而,随着 Hibernate 4.0 的变化,我们现在被建议使用新的Integrator
接口来进行服务发现。这包括为触发器添加事件侦听器,例如postUpdate
等postDelete
。
不幸的是,这不能很好地与通过注释依赖项进行的依赖项注入配合使用。我有以下设置:
我定义的集成器将我的侦听器添加到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);
}
我还定义了 class MyListener
,它看起来像您的典型事件侦听器。
@Component
public class MyListener implements PostInsertEventListener {
@Autowired
private Dependent dependent;
public void onPostInsert(PostInsertEvent event) {
// dependent == null
}
}
不幸的是,如评论所示,这不起作用。我想这是因为我在MyListener
内部实例化MyIntegrator
,它不会拾取组件并且不会自动装配组件。但是,如果我尝试这个:
@Component
public class MyIntegrator {
@Autowired
private MyListener listener;
...
}
然后侦听器不会自动装配。
首先,使用 Spring 必须做的事情感觉不对new MyListener()
。我希望能够将其定义为自动装配的依赖项,并让 Spring 为我创建一个单例。我的问题是这样的:
在新的 Integrator 接口中使用依赖注入的最佳方法是什么?Integrator 用于构建 SessionFactory,因此当他们被要求集成自己时,我想没有可用的应用程序上下文。因此,我在 Integrator 中需要的任何 bean 都需要以“老式”方式创建,并且不会收到它们的自动装配。
我对 Spring 的世界很陌生,你会说这是我应该期待看到的吗?我知道当我在 SessionFactory 中时,我处于应用程序的不同范围内,但是有没有办法获得对 bean 的引用并启用自动装配,即使我是通过创建它的new
?
我想出的解决方案使用了ApplicationContextAware
. 这意味着只要上下文可用,就会MyListener
收到ApplicationContext
对 bean 的引用,并且我在方法调用而不是 bean 构造时从上下文中引用 bean。创建一个 beannew
并没有限制这一点,所以 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);
}
}
有没有更好的办法?