Как автоматически связать интерфейс или абстрактный класс без реализации в Spring - PullRequest
0 голосов
/ 18 сентября 2018

Мне нужно автоматически подключить интерфейс без реализации, что-то вроде функциональности тега @Repository.

@QueryRepository
public interface EddressBookDao {

    @ReportQuery
    public List<EddressBookDto> loadEddresses(@EqFilter("id") Long id);

}

@Autowired
private EddressBookDao eddressBookDao;

Result result = eddressBookDao.loadEddresses(1L);

Я подумываю как-то обнаружить мою @QueryRepository аннотацию во время ClassPathScan и внедрить прокси EddressBookDao объект на eddressBookDao Autowire.

Сейчас я выполняю эту функцию громоздким способом, используя следующее:

@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 голосов
/ 19 сентября 2018

Spring Data не поддерживает автоматическое подключение интерфейсов, хотя может выглядеть так.Он регистрирует фабрики, которые производят прокси, реализующие интерфейс.

Чтобы сделать нечто подобное, вы должны реализовать интерфейс FactoryBean.См. JavaDoc для деталей .Также доступно учебных пособий .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...