如何在不实现Spring的情况下自动装配接口或抽象类

时间:2018-09-18 18:45:45

标签: spring hibernate spring-boot spring-data-jpa spring-data

我需要在没有实现的情况下自动装配接口,就像 @存储库标签功能。

@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;

1 个答案:

答案 0 :(得分:1)

Spring Data不会自动装配接口,尽管它看起来可能是这样。它注册产生实现该接口代理的工厂。

要执行类似的操作,您必须实现FactoryBean接口。 参见the JavaDoc for details。也有tutorials available