spring中BeanPostProcessor 实现策略模式

视频解码枚举

public enum VideoType {

    WMV("wmv"),
    AVI("avi");

    private String desc;

    VideoType(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}

解码接口

public interface IDecoder {

    VideoType type();

    String decode(String data);
}

WMV解码功能

@Service
public class WMVDecoder implements IDecoder {
    @Override
    public VideoType type() {
        return VideoType.WMV;
    }

    @Override
    public String decode(String data) {
        return this.type().getDesc() + ": " + data;
    }
}

AVI解码功能

@Service
@Slf4j
public class AVIDecoder implements IDecoder, InitializingBean {
    @Override
    public VideoType type() {
        return VideoType.AVI;
    }

    @Override
    public String decode(String data) {
        return this.type().getDesc() + " : " + data;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("init AVIDecoder afterPropertiesSet");
    }
}

解码Manager

实现 BeanPostProcessor接口,并缓存 VideoType 与 IDecoder对应关系

@Service
@Slf4j
public class DecodeManager implements BeanPostProcessor {

    private static final Map<VideoType, IDecoder> viderTypeInedx =
            new HashMap<>(VideoType.values().length);

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if (!(bean instanceof IDecoder)) {
            return bean;
        }
        IDecoder decoder = (IDecoder) bean;
        VideoType type = decoder.type();
        if (viderTypeInedx.containsKey(type)) {
            throw new IllegalStateException("重复注册");
        }
        log.info("Load Decode {} for video type{} ", decoder.getClass(), type.getDesc());
        viderTypeInedx.put(type, decoder);
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof IDecoder)) {
            return bean;
        }
        log.info("BeanPostProcessor after init :{}", bean.getClass());
        return null;
    }

    public String decode(VideoType type, String data) {
        String result = null;
        switch (type) {
            case AVI:
                result = viderTypeInedx.get(VideoType.AVI).decode(data);
                break;
            case WMV:
                result = viderTypeInedx.get(VideoType.WMV).decode(data);
                break;
            default:
                log.info("error");
        }
        return result;
    }
}

测试用例:

  @Autowired
    private DecodeManager decodeManager;

    @Test
    public void testDecode() {
        //获取随机解码器
        VideoType videoType = VideoType.values()[new Random().nextInt(VideoType.values().length)];

        decodeManager.decode(videoType, "解码数据~");
    }

上一篇:Spring IOC容器提供的扩展接口


下一篇:Spring的BeanPostProcessor及部分默认实现