目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| com.demo.mytest ├── strategy │ ├── anno │ │ ├── BaseDealAnno.java(注解) │ ├── enums │ │ ├── BasePluginEnum.java(枚举) │ ├── factory │ │ ├── BaseDealFactory.java │ ├── listener │ │ ├── ContextBaseDealListener.java(核心类) │ ├── service │ │ ├── impl │ │ │ ├── BaseAudioService.java │ │ │ ├── BaseDocumentService.java │ │ │ ├── BaseImageService.java │ │ └── BaseDealHandler.java(接口) └── MytestApplication.java
|
实现
BaseDealAnno.java(注解)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import com.demo.mytest.strategy.enums.BasePluginEnum; import org.springframework.stereotype.Indexed;
import java.lang.annotation.*;
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Indexed public @interface BaseDealAnno { BasePluginEnum[] value(); }
|
BasePluginEnum.java(枚举)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public enum BasePluginEnum { DOCUMENT, IMAGE, LINK, AUDIO_RECORD, AUDIO, }
|
BaseDealFactory.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import com.demo.mytest.strategy.enums.BasePluginEnum; import com.demo.mytest.strategy.service.BaseDealHandler; import lombok.extern.slf4j.Slf4j;
import java.util.HashMap; import java.util.Map;
@Slf4j public class BaseDealFactory {
private static Map<BasePluginEnum, BaseDealHandler> handlerMap = new HashMap<>();
public static void registerStrategy(BasePluginEnum pluginEnum, BaseDealHandler handler) { handlerMap.put(pluginEnum, handler); }
public static BaseDealHandler loadHandler(BasePluginEnum pluginEnum) throws Exception { if (handlerMap.containsKey(pluginEnum)) { BaseDealHandler handler = handlerMap.get(pluginEnum); log.info("loadHandler {} {}", pluginEnum, handler.getClass()); return handler; } else { throw new RuntimeException("未配置相应处理策略 " + pluginEnum); } } }
|
ContextBaseDealListener.java(核心类)
项目启动就加载并注册。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import cn.hutool.extra.spring.SpringUtil; import com.demo.mytest.strategy.anno.BaseDealAnno; import com.demo.mytest.strategy.enums.BasePluginEnum; import com.demo.mytest.strategy.factory.BaseDealFactory; import com.demo.mytest.strategy.service.BaseDealHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.aop.support.AopUtils; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component;
import java.util.Map;
@Component @Slf4j public class ContextBaseDealListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { log.info("容器初始化完毕");
Map<String, Object> controllers = SpringUtil.getApplicationContext().getBeansWithAnnotation(BaseDealAnno.class); for (Map.Entry<String, Object> entry : controllers.entrySet()) { Object value = entry.getValue(); BaseDealHandler handler = (BaseDealHandler) value;
Class<?> aClass = AopUtils.getTargetClass(value); BaseDealAnno Anno = aClass.getDeclaredAnnotation(BaseDealAnno.class); log.info("加载:load beanName -> {}, {}", handler.getClass(), Anno.value());
if (null != Anno.value()) { for (BasePluginEnum pluginEnum : Anno.value()) { log.info("注册:register -> {}, {}", handler.getClass(), Anno.value()); BaseDealFactory.registerStrategy(pluginEnum, handler); } } } }
}
|
BaseDealHandler.java(接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.util.Map;
public interface BaseDealHandler<RES> {
Object process(Map<String, RES> req); }
|
BaseAudioService.java(可扩展多个)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import com.demo.mytest.strategy.anno.BaseDealAnno; import com.demo.mytest.strategy.enums.BasePluginEnum; import com.demo.mytest.strategy.service.BaseDealHandler; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service;
import java.util.Map;
@Slf4j @Service @BaseDealAnno(value = BasePluginEnum.AUDIO) @RequiredArgsConstructor public class BaseAudioService implements BaseDealHandler<String> {
@Override public Object process(Map<String, String> req) { log.info("process 音频处理完成。"); return new Object(); } }
|
验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import cn.hutool.json.JSONUtil; import com.demo.mytest.strategy.enums.BasePluginEnum; import com.demo.mytest.strategy.factory.BaseDealFactory; import com.demo.mytest.strategy.service.BaseDealHandler; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.util.StopWatch;
import java.util.HashMap; import java.util.Map;
@SpringBootTest class BaseAudioServiceTest {
@Test void process() throws Exception { BasePluginEnum plugin = BasePluginEnum.AUDIO; BaseDealHandler baseDealHandler = BaseDealFactory.loadHandler(plugin); StopWatch sw = new StopWatch(); sw.start(); Map<String, Object> req = new HashMap<>(); System.out.println("process start: req -> " + JSONUtil.toJsonStr(req)); Object resObj = baseDealHandler.process(req); sw.stop(); System.out.println("process end " + sw.getTotalTimeSeconds() + ": res -> {}" + JSONUtil.toJsonStr(resObj)); } }
|
2023-11-16 15:13:23.459 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 容器初始化完毕
2023-11-16 15:13:23.461 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 加载:load beanName -> class com.demo.mytest.strategy.service.impl.BaseAudioService, [AUDIO]
2023-11-16 15:13:23.464 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 注册:register -> class com.demo.mytest.strategy.service.impl.BaseAudioService, [AUDIO]
2023-11-16 15:13:23.465 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 加载:load beanName -> class com.demo.mytest.strategy.service.impl.BaseDocumentService, [DOCUMENT]
2023-11-16 15:13:23.465 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 注册:register -> class com.demo.mytest.strategy.service.impl.BaseDocumentService, [DOCUMENT]
2023-11-16 15:13:23.465 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 加载:load beanName -> class com.demo.mytest.strategy.service.impl.BaseImageService, [IMAGE]
2023-11-16 15:13:23.465 INFO 5043 — [ main] c.d.m.s.l.ContextBaseDealListener : 注册:register -> class com.demo.mytest.strategy.service.impl.BaseImageService, [IMAGE]
2023-11-16 15:13:23.469 INFO 5043 — [ main] c.d.m.s.s.impl.BaseAudioServiceTest : Started BaseAudioServiceTest in 1.382 seconds (JVM running for 2.726)
2023-11-16 15:13:23.643 INFO 5043 — [ main] c.d.m.strategy.factory.BaseDealFactory : loadHandler AUDIO class com.demo.mytest.strategy.service.impl.BaseAudioService
process start: req -> {}
2023-11-16 15:13:23.665 INFO 5043 — [ main] c.d.m.s.service.impl.BaseAudioService : process 音频处理完成。