直接上代码,现在业务中用的
首先定义一个注解,通过此注解来注册策略
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ActionType {
String value();
}
定义action,业务通过此type来获取不同的策略
public class ActionTypeConstant {
public static final String ACTION_TYPE_TEST = "test";
public static List<String> actionTypes = new ArrayList<>();
static {
actionTypes.add(ACTION_TYPE_TEST);
}
public static boolean checkInActions(String actionType) {
return actionTypes.contains(actionType);
}
}
策略接口
public interface IStrategy {
boolean action(Object obj);
}
定义一个帮助类,用来注册策略
@Component
class StrategyService {
@Autowired
private List<IStrategy> strategies;
private static Map<String, IStrategy> STRATEGIES_MAP = new HashMap();
@PostConstruct
private void init () {
if (CollectionUtils.isEmpty(strategies)) {
return;
}
for (IStrategy strategy : strategies) {
String key = null;
key = strategy.getClass().getAnnotation(ActionType.class).value();
if (!StringUtils.isEmpty(key)) {
STRATEGIES_MAP.put(key, strategy);
}
}
}
public IStrategy getStrategy (String actionType){
Preconditions.checkArgument(PoolActionTypeConstant.checkInActions(actionType), "action type error");
return STRATEGIES_MAP.get(actionType);
}
}
注册策略也可以用另一种方法
// 定义一个容器保存策略
@Component
public class StrategyContainer {
public static Map<String, IStrategy> strategyContainer = new ConcurrentHashMap<>();
public static void register(String actionType, IStrategy strategy) {
Assert.notNull(actionType, "action type can`t be null");
Assert.notNull(strategy, "strategy can`t be null");
strategyContainer.put(actionType, strategy);
}
public static IStrategy getStrategy(String actionType) {
Assert.notNull(actionType, "action type can`t be null");
return strategyContainer.get(actionType);
}
}
// 每个策略中注册自己
@Slf4j
@Service
@ActionType("test")
class TestStrategy implements IStrategy, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
StrategyContainer.register(this.getClass().getAnnotation(ActionType.class).value(), this);
}
}
业务使用策略
strategyService.getStrategy(ActionTypeConstant.ACTION_TYPE_TEST).action(object);