Home > database >  Spring ReflectionUtils for Generic Classes
Spring ReflectionUtils for Generic Classes

Time:07-29

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.

CodePudding user response:

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.

  • Related