2017-02-03 8 views
14

I имеет следующую структуру:Java CDI: декоратор с несколькими родового Params

@Decorator 
public abstract class MyDecorator<T extends BaseEntity, Q extends QueryParams> implements EntityService<T, Q> { 

    @Any 
    @Inject 
    @Delegate 
    EntityService<T, Q> delegate; 

    @Override 
    public T save(T entity) { ... } 

} 

Это объявление EntityService интерфейса:

public interface EntityService<T extends BaseEntity, Q extends QueryParams> { 

    T save(T entity); 

    void deleteById(Integer id); 

    void deleteAllById(List<Integer> ids); 

    void delete(T entity); 

    void deleteAll(List<T> entities); 

    T findById(Integer id); 

    QueryResultWrapper<T> query(Q parameters); 

    Long count(Q parameters); 

} 

К сожалению, декоратор метод сохранения никогда не дозвонился, когда она должна , хотя никаких ошибок не обнаружено ... Единственный способ, которым я работал, был такой:

@Decorator 
public abstract class MyDecorator<T extends BaseEntity> implements EntityService<T> { ... } 

Без Q extends QueryParams общий параметр.

MyDecorator указано внутри beans.xml.

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
    bean-discovery-mode="all" version="1.1"> 

    <decorators> 
     <class>fortuna.backend.comum.decorators.MyDecorator</class> 
    </decorators> 

</beans> 

Любые подсказки?

+0

Возможно, вам потребуется предоставить дополнительную информацию. Я попытался сделать быстрый фрагмент с приведенным выше, и это просто сработало для меня (используя Weld, который, как я полагаю, вы также используете). Также в вашем вопросе вы говорите о «EntityService», но покажете фрагмент кода с «CrudService». Это опечатка или есть другой общий класс между ними? – Siliarus

+0

Опечатка, извините, только исправлена. В любом случае, какую дополнительную информацию я могу предоставить? –

+1

Не могли бы вы предоставить свой файл beans.xml? – hya

ответ

1

Удалось решить проблему. Моя проблема заключалась в том, что я использую QueryParams непосредственно в большинстве реализаций конечных точек/услуг, например:

public class PersonService extends EntityService<Person, QueryParams> { ... }

В самом деле, QueryParams фактически не extends QueryParams, это класс сам по себе! Вот почему PersonService не запускал MyDecorator вообще!

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

public abstract class MyDecorator<T extends BaseEntity, Q extends IQueryParams> implements EntityService<T, Q> {

Теперь PersonService сохранить метод делает вызвать MyDecorator.

0

Вы делаете это ->

EntityService<T extends BaseEntity, Q extends QueryParams> 

Если интерфейс взять два объекта, один T расширяет BaseEntity, другой Q расширяет QueryParams, соответственно, вы можете попробовать прямо поставить конкретные типы вместо. Так же, как это:

К интерфейсу (Здесь самое главное, чтобы быть столь же общим, как Возможное, таким образом, вы выбираете два имени, как A, B, или в вашем случае):

public interface EntityService<T, Q> { 

T Save(T param); 

void otherMethod(Q param); 

}

к декоратора (Здесь, в этой точке, вы можете выбрать типы, поэтому не necesary быть "общий"):

public abstract class MyDecorator implements EntityService<BaseEntity, QueryParams>{ 

@Any 
@Inject 
@Delegate 
EntityService<BaseEntity, QueryParams> delegate; 
//If I understood well the problem, this just work and solve your problem, 
//or else... I'm sorry, you can give me more data so I could help you 
//a little more 

//Check here, I give a concrete type for T abstract generic type, in 
//your case BaseEntity 
@Override 
public BaseEntity save(BaseEntity entity) { 
    BaseEntity retSomething; //this is ilustrative 
    super.save(entity); //save your entity as you know how. 
    return retSomething; //I really don't know why your save method has a 
         //return statament, but, if you need it, check the 
         //return type 
} 

@Override 
public void otherMethod(QueryParams param) { 
    // Check here, in the interface the name was Q, now here you only 
    // can use as param an QueryParams type object 

} 

}

+0

Привет, Дамиан, прежде всего, спасибо за ваш ответ. Но теперь, как насчет экземпляра «@ Delegate»? Он должен знать конкретный тип, а не просто супертип, чтобы его правильно вводили. @Damian Lattenero –

+0

Хорошо, я изменю свой первоначальный ответ, чтобы ответить на этот вопрос. –

+0

И, извините, ответ Да, экземпляр @Delegate ДОЛЖЕН знать конкретный (более приятный, чем определенный) тип. Дайте мне знать, если это работает –