Java CDI:具有多个通用参数的装饰器
Java CDI: Decorator with multiple generic 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>
有什么线索吗?
您正在这样做 ->
EntityService<T extends BaseEntity, Q extends QueryParams>
如果那个接口带两个Object,一个T extends BaseEntity,另一个Q extends QueryParams,分别可以试试直接放Specific types代替。就像这样:
界面(在这里,最重要的是尽可能通用,因此,您选择两个名称,如 A、B,或者在您的情况下):
public interface EntityService<T, Q> {
T Save(T param);
void otherMethod(Q param);
}
致装饰器(这里,此时可以选择类型,所以不必"generic"):
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
}
}
已成功解决问题。我的问题是我在大多数 endpoints/services 实现中直接使用 QueryParams
,例如:
public class PersonService extends EntityService<Person, QueryParams> { ... }
其实QueryParams
其实并不是extends QueryParams
,而是class本身!这就是 PersonService
根本没有触发 MyDecorator
的原因!
因此我创建了一个名为 IQueryParams
的接口并使用它,就像这样:
public abstract class MyDecorator<T extends BaseEntity, Q extends IQueryParams> implements EntityService<T, Q> {
现在 PersonService
保存方法会触发 MyDecorator
。
我有以下结构:
@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>
有什么线索吗?
您正在这样做 ->
EntityService<T extends BaseEntity, Q extends QueryParams>
如果那个接口带两个Object,一个T extends BaseEntity,另一个Q extends QueryParams,分别可以试试直接放Specific types代替。就像这样:
界面(在这里,最重要的是尽可能通用,因此,您选择两个名称,如 A、B,或者在您的情况下):
public interface EntityService<T, Q> {
T Save(T param);
void otherMethod(Q param);
}
致装饰器(这里,此时可以选择类型,所以不必"generic"):
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
}
}
已成功解决问题。我的问题是我在大多数 endpoints/services 实现中直接使用 QueryParams
,例如:
public class PersonService extends EntityService<Person, QueryParams> { ... }
其实QueryParams
其实并不是extends QueryParams
,而是class本身!这就是 PersonService
根本没有触发 MyDecorator
的原因!
因此我创建了一个名为 IQueryParams
的接口并使用它,就像这样:
public abstract class MyDecorator<T extends BaseEntity, Q extends IQueryParams> implements EntityService<T, Q> {
现在 PersonService
保存方法会触发 MyDecorator
。