Reputation: 2245
There exist following classes
class Entity{
}
class Dto{
}
public abstract class BaseMapper<E extends Entity, D extends Dto>{
}
And several sepcific implementation of mappers like:
FooMapper extends BaseMapper<Foo, FooDto>{
}
FeeMapper extends BaseMapper<Fee, FeeDto>{
}
No I want to integrate some "Wrapper" which does a bit more than normal mapping of the data, because I got a new concept/issue
@Component
public final class RevMapper<ENTITY extends Entity, DTO extends Dto> {
private BaseMapper<ENTITY, DTO> baseMapper;
@Autowired
public <MAPPER extends BaseMapper<ENTITY, DTO>> RevMapper(MAPPER mapper) {
this.baseMapper = mapper;
}
public List<RevDto<DTO>> toDto(final List<Rev<ENTITY>> revList) {
for(Rev<ENTITY> rev: revList){
...
baseMapper.toDto(rev.getEntity(), true);
}
...
}
}
And include it in my service like:
@Autowired
private RevMapper<Foo, FooDto> fooRevMapper;
The problem now is:
Parameter 0 of constructor in com.test.package.RevMapper required a single bean, but 2 were found: - FooMapper - FeeMapper
Spring doesn't know which to take. And yeah what I know is about the type erasure in generics. So basically after compile the application just know that there is a
RevMapper<Entity,Dto>
but not which type it is specifically. How could I tell Spring to insert the right component, or how would you handle this problem. I do not want to write the same lines of code for each type of Mapper....
Upvotes: 1
Views: 720
Reputation: 19926
The solution I can think of is not as time consuming than creating many many subclasses.
First make the RevMapper not a @Component
and then create a class like follows:
@Configuration
public final class Mappers{
private final FooMapper fooMapper;
private final FeeMapper feeMapper;
@Autowired
public Mappers(FooMapper fooMapper, FeeMapper feeMapper){
this.fooMapper = fooMapper;
this.feeMapper = feeMapper;
}
@Bean
public RevMapper<Foo, FooDto> fooRevMapper(){
return new RevMapper(fooMapper);
}
@Bean
public RevMapper<Fee, FeeDto> feeRevMapper(){
return new RevMapper(feeMapper);
}
}
It's no more than just creating a method for every different RevMapper
you want to provide.
Upvotes: 1