How to elegantly use automatic injection to implement strategy pattern in spring boot

Preface

Relationship description: PayService is the payment interface, and the core business method is epay(). This interface has several different implementation classes.
Requirements: The logic of which implementation class needs to be dynamically decided at runtime.

solution

First, the finished product code:

@Service
public class RouteService {
    
    
 
    @Autowired
    Set<PayService> payServiceSet;
    
    Map<String, PayService> payServiceMap;
 
    public PayResult epay(PayRequest payRequest) {
    
    
        PayService payService = payServiceMap.get(payRequest.getChannelNo());
        return  payService.epay(payRequest);
    }
 
    @PostConstruct
    public void init() {
    
    
        for (PayService payService : payServiceSet) {
    
    
            payServiceMap = new HashMap<>();
            payServiceMap.put(payService.channel(), payService);
        }
    }
}

code analysis

Using Set<PayService>a type will cause Spring to PayServiceinject all classes that implement the interface into the Set.

@Autowired
Set<PayService> payServiceSet;

Map<String, PayService>Used to save the mapping relationship between implementation classes and calling judgment logic.

Map<String, PayService> payServiceMap;

The init method decorated with @PostConstructannotations will be automatically executed when the Spring container starts, where the mapping Map is constructed.
The payService channel()method comes from the interface definition. The PayService interface requires each implementation class to implement this method, and this method will return the unique identifier of different implementation classes.

@PostConstruct
public void init() {
    
    
    for (PayService payService : payServiceSet) {
    
    
        payServiceMap = new HashMap<>();
        payServiceMap.put(payService.channel(), payService);
    }
}

When calling, the request parameter must carry a unique identifier to indicate which implementation class needs to be used for this call, which is the value of the Key in the above mapping Map.

public PayResult epay(PayRequest payRequest) {
    
    
   PayService payService = payServiceMap.get(payRequest.getChannelNo());
   return  payService.epay(payRequest);
}

Reference article

Quickly implement the strategy pattern using Spring automatic injection

Guess you like

Origin blog.csdn.net/Ka__ze/article/details/132533232