Strategy Pattern with Spring Boot

Asked

Viewed 770 times

3

I’ve been looking for solutions for Strategy Pattern with spring boot, but nothing I’ve found so far seems performatic or even functional.

I have an interface like:

public interface UserService {
    User getById(Integer id);
}

And I have two separate injections:

@Primary
@Service("userService")
public class UserServiceImpl implements UserService{

    @Override
    public User getById(Integer id){
    //todo here
    }
}

@Service("userRemoteService")
public class UserRemoteServiceImpl implements UserService{

    @Override
    public User getById(Integer id){
    //todo here
    }
}

On the controller I call the interface:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    //some methods here

}

The way it’s just the UserServiceImpl will be instantiated and called, for it is the Primary.

The application can have two states, one in which it queries the local bank and the other where it requests a microservice. I need that when the state changes (some request in an endpoint will let me know and it’s already implemented) I change the Userservice implementation that will be consumed by the controller.

I found some solutions, most are versions of if Else. I need to find some solution that when I do a state refresh Scope and it changes, without checking every request I have the right Userservice implementation in the controller.

  • 2

    See if this helps you: https://lofidewanto.blogspot.com.br/2013/06/creating-spring-bean-dynamically-in.html

1 answer

4


Here’s an alternative. I hope it helps!

Interface:

public interface UserService {
  User getById(Integer id);
}

Implementations:

@Bean(name = "userLocalService")
public class UserServiceImpl implements UserService{

  @Override
  public User getById(Integer id){
    //todo here
  }
}

@Bean(name = "userRemoteService")
public class UserRemoteServiceImpl implements UserService{

  @Override
  public User getById(Integer id){
    //todo here
  }
}

Factory interface:

public interface UserServiceFactory {
  UserService getUserService(String userServiceType);
}

Configuration class:

@Configuration()
public class UserServiceConfig {

  @Bean
  public UserService userServiceImpl() {
    return new UserServiceImpl();
  }

  @Bean
  public UserService UserRemoteServiceImpl() {
    return new UserRemoteServiceImpl();
  }

  @Bean
  public ServiceLocatorFactoryBean serviceLocatorFactoryBean() {
    ServiceLocatorFactoryBean serviceLocatorFactoryBean = new ServiceLocatorFactoryBean();
    serviceLocatorFactoryBean.setServiceLocatorInterface(UserServiceFactory.class);
    return serviceLocatorFactoryBean;
  }

  @Bean
  public ConditionUserService() {
      return new ConditionUserService();
  }
}

Service that will define which implementation to use:

@Service
public class ConditionUserService() {

  private String userServiceType = "userLocalService";

  @Autowired
  private UserServiceFactory userServiceFactory;

  public UserService getUserService() {
    return userServiceFactory.getUserService(userServiceType);
  }

  public setUserServiceType(String userServiceType) {
    this.userServiceType = userServiceType;
  }

}

Controller:

@Controller
public class UserController {

  @Autowired
  private ConditionUserService conditionUserService;

  public User getById(Integer id) {
        UserService userService = conditionUserService.getUserService();
        return userService.getById(id);
    }

}

The moment you want to change the behavior you will call:

conditionUserService.setUserServiceType("userRemoteService");

Browser other questions tagged

You are not signed in. Login or sign up in order to post.