Issue
I'm Using Spring RefectionUtils to set a field named "type" for the Generic Class GenericServiceImpl:
The GenericServiceImpl is an implementation of the interface GenericService
public interface GenericService<T>{ }
public class GenericServiceImpl<T> implements GenericService<T>{
public Class<T> type;
public GenericServiceImpl(Class<T> type){
this.type = Objects.requireNonNull(type);
}
public GenericServiceImpl(){ }
}
My purpose consists of setting the attribute type with a generic class value, I will give you an example: I have two beans of type GenericService beanA and beanB that have respectively two classes A and B as Generic type. I have another Service class MyService that injects these latter.
@Service
public class MyService{
private final GenericService<A> beanA;
private final GenericService<B> beanB;
public MyService(GenericService<A> beanA,GenericService<B> beanB){
this.beanA=beanA;
this.beanB=beanB;
}
}
So I'd like to set the attribute type of beanA with A.class as value, the same for beanB with B.class;
I want to achieve this latter with Java reflection API or using Spring frameworks that make the use of Refection API easier.
So I have added a method named init() annotated with @PostConstruct in MyService class.
@PostConstruct
public void init() {
ReflectionUtils.doWithFields(beanA.getClass(),
(Field field) -> {
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, beanA, A.class);
},
(Field field) -> field.getType() == Class.class
);
ReflectionUtils.doWithFields(beanB.getClass(),
(Field field) -> {
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, beanB, B.class);
},
(Field field) -> field.getType() == Class.class
);
}
But I found that manner of implementation is messy because the field "type" has B.class the value in both beans: beanA and beanB !!
Thanks for your help.
Solution
The instances injected into MyService
should already be completely set up.
Why not do something like:
@Configuration
class MyConfig {
@Bean
GenericService<A> aService() {
return new GenericService(A.class);
}
@Bean
GenericService<B> bService() {
return new GenericService(B.class);
}
}
Perhaps you can explain better what you are trying to achieve with your class structure, instead of the particular problem you are having using it this way.
Answered By - tgdavies
Answer Checked By - David Marino (JavaFixing Volunteer)