【发布时间】:2019-02-22 20:37:21
【问题描述】:
我需要自动装配一个没有实现的接口,就像 @Repository 标记功能。
@QueryRepository
public interface EddressBookDao {
@ReportQuery
public List<EddressBookDto> loadEddresses(@EqFilter("id") Long id);
}
@Autowired
private EddressBookDao eddressBookDao;
Result result = eddressBookDao.loadEddresses(1L);
我正在考虑在 ClassPathScan 期间以某种方式检测我的 @QueryRepository 注释并在 eddressBookDao Autowire 上注入 EddressBookDao 对象的代理。
现在我正在使用以下方法以繁琐的方式实现此功能:
@Autowired
public ReportQueryInvocationHandler reportQuery;
private EddressBookDao eddressBookDao;
public EddressBookDao eddressBook(){
if (eddressBookDao == null) eddressBookDao = reportQuery.handle(EddressBookDao.class);
return eddressBookDao;
}
这是我创建代理的处理程序:
@Component
public class ReportQueryInvocationHandler implements InvocationHandler {
public <T> T handle(Class<T> clazz){
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws NoSuchFieldException, IllegalAccessException {
Type returnType = method.getReturnType();
Annotation[][] annotations = method.getParameterAnnotations();
Report report = dao.createReport();
for (int i = 0; i < args.length; i++) {
Object argument = args[i];
Annotation[] annotationList = annotations[i];
if (annotationList.length == 0) continue;
for (Annotation annotation : annotationList) {
Class<? extends Annotation> annotationType = annotation.annotationType();
String path = null;
if (annotationType.equals(EqFilter.class)) {
path = ((EqFilter) annotation).value();
report.equalsFilter(path, argument);
break;
}
}
}
return report.list((Class<?>) returnType);
}
我是这样称呼它的:
List<EddressBookDto> addressed = dao.eddressBook().loadEddresses(8305L);
我只想避免编写这段代码
private EddressBookDao eddressBookDao;
public EddressBookDao eddressBook(){
if (eddressBookDao == null) eddressBookDao = reportQuery.handle(EddressBookDao.class);
return eddressBookDao;
}
改为这样写:
@Autowired
private EddressBookDao eddressBookDao;
【问题讨论】:
-
基本上我有自己的 Hibernate 实现,我根据 ReturnType EddressBookDto 和 Param 中的过滤器动态构建自己的 Criteria。我想我应该使用与 @Repository 相同的逻辑并使用 AOP 拦截方法来创建查询并返回结果。
标签: spring hibernate spring-boot spring-data-jpa spring-data