简体   繁体   中英

Factory for Spring Beans implementing interface

Considering a project of many entities, I have a service that requires to know the entity's type to execute a method. I created;

interface Service<T> {
  String myMethod(T entity)
  Class<T> getResponsibility()

And for example;

class FooService<Foo> {
  String myMethod(Foo entity) { return 'foo'; }
  Class<Foo> getResponsibility() { return Foo.class }

I wanted to create a factory to return the correct Bean (I'm using Spring Boot) to use, which I defined:

class ServiceFactory {
  List<Service<?>> services;
  
  @Autowired
  public ServiceFactory(List<Service<?>> services) {
    this.services = services;
  }

  Service getFor(Object entity) {
    // Simplified for comprehension purpose
    return this.services.stream().filter(service -> service.getResponsibility().equals(entity.getClass()).get();
}

This works, but I have a (sonar) warning saying that I should not make 'raw' use of Service as return type for my factory method. What is the correct way of achieving this? Using a wildcard is another warning.

The goal is to have a factory that returns the correct Bean. Is the initial design wrong?

Instead of passing an object, pass the class itself and capture it as a method type parameter:

<T> Service<T> getFor(Class<T> type) {

You'd still get a warning because the injected list uses a wildcard:

@SuppressWarnings("unchecked")
<T> Service<T> getFor(Class<T> type) {
    // Simplified for comprehension purpose
    return (Service<T>) this.services.stream()
            .filter(service -> service.getResponsibility().equals(type))
            .findFirst()
            .get();
}

You might be better off using Spring's support for generics by injecting directly the specific service:

@Autowired
Service<Foo> fooService;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM