1、定义一个注入的接口
public interface DependencyInjector {
void performInjection(Object existingBean);
}
2、定义一个实现了注入接口 DependencyInjector 及 BeanFactoryAware 的属性注射器 bean
public class AutowireDependencyInjector implements DependencyInjector, BeanFactoryAware{
private AutowireCapableBeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof AutowireCapableBeanFactory))
throw new IllegalArgumentException("BeanFactory must" + " be an AutowireCapableBeanFactory");
this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
}
//将属性(spring中注册过的)绑定到 bean 上
public void performInjection(Object existingBean) {
beanFactory.autowireBeanProperties(existingBean,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
}
}
3、定义一个监听器,监听 entity 生成后不同的事件类型,然后将属性注入
public class DependencyInjectionEntityListener {
private static DependencyInjector _injector;
public static void setInjector(DependencyInjector injector) {
_injector = injector;
}
//如果需要监听不同的事件,以下方式类推
@PrePersist
@PostLoad
public void performInjection(Object entity) {
if (_injector == null)
throw new IllegalStateException("EntityListener cannot"
+ " be used without an injector");
_injector.performInjection(entity);
}
}
4、定义一个监听配置类,将属性注射器注入到监听器中
public class DependencyInjectionEntityListenerConfigurer implements InitializingBean{
private DependencyInjector injector;
public void setInjector(DependencyInjector injector) {
if (injector == null)
throw new NullPointerException("Injector cannot be null");
this.injector = injector;
}
public void afterPropertiesSet() throws Exception {
DependencyInjectionEntityListener.setInjector(injector);
}
}
5、entity 类使用
@Entity
// 自定义的 listener
@EntityListeners(DependencyInjectionEntityListener.class)
public class DomainObject {
@Id
private long id;
DomainObject() {
}
public DomainObject(long id) {
this.id = id;
}
public long getId() {
return id;
}
//需要注入的属性
@Transient
private SomeService service;
public void setService(SomeService service) {
this.service = service;
}
}
关键点在于 AutowireCapableBeanFactory.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);, 将spring中的属性注入到 JPA entity, 以及用到了JPA 的 EntityListeners.