1.SpringBoot集成策略模式和工厂模式
1.1 SpringBoot结构图
1.2 编写接口(用于扩展)
1 | public interface Strategy { |
2 | String doOperation(); |
3 | } |
1.3 编写实现类
1 | |
2 | (value = "1", zclass = Strategy.class) //该注解在本文后面定义 |
3 | public class StrategyOne implements Strategy { |
4 | |
5 | public String doOperation() { |
6 | return "one"; |
7 | } |
8 | } |
1 | |
2 | (value = "2", zclass = Strategy.class)//该注解在本文后面定义 |
3 | public class StrategyTwo implements Strategy { |
4 | |
5 | public String doOperation() { |
6 | return "two"; |
7 | } |
8 | } |
1 | |
2 | (value = "3", zclass = Strategy.class)//该注解在本文后面定义 |
3 | public class StrategThree implements Strategy { |
4 | |
5 | public String doOperation() { |
6 | return "three"; |
7 | } |
8 | } |
1.4 定义自定义注解
1 | ({ElementType.TYPE}) |
2 | (RetentionPolicy.RUNTIME) |
3 | |
4 | |
5 | public HandlerType { |
6 | |
7 | /** |
8 | * 策略类型 |
9 | * @return |
10 | */ |
11 | String value(); |
12 | |
13 | /** |
14 | * 接口class类 |
15 | * @return |
16 | */ |
17 | Class<?> zclass(); |
18 | |
19 | } |
1.5 定义处理器,用来处理标识的Service类
1 | |
2 | public class HandlerProcessor implements ApplicationContextAware { |
3 | /** |
4 | * 获取所有的策略Beanclass 加入HandlerOrderContext属性中 |
5 | * |
6 | * @param applicationContext 上下文 |
7 | * @throws BeansException 没有实体的异常 |
8 | */ |
9 | |
10 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
11 | //获取所有策略注解的Bean |
12 | Map<String, Object> handlerMap = applicationContext.getBeansWithAnnotation(HandlerType.class); |
13 | handlerMap.forEach((k, v) -> { |
14 | // 获取对应的对象 |
15 | Class<?> handlerclass = v.getClass(); |
16 | // 注解中的type |
17 | String type = handlerclass.getAnnotation(HandlerType.class).value(); |
18 | // 注解中的zclass |
19 | Class<?> zclass = handlerclass.getAnnotation(HandlerType.class).zclass(); |
20 | //将class加入map中,type作为key |
21 | Map<String, Class<?>> factoryMap = ConversionFactory.conversionFactoryMap.get(zclass); |
22 | if (null == factoryMap) { |
23 | factoryMap = new HashMap<>(); |
24 | factoryMap.put(type, handlerclass); |
25 | }else { |
26 | factoryMap.put(type, handlerclass); |
27 | } |
28 | ConversionFactory.conversionFactoryMap.put(zclass, factoryMap); |
29 | }); |
30 | } |
31 | } |
1.6 定义转换工厂
1 | |
2 | 4j |
3 | public class ConversionFactory<T> { |
4 | |
5 | //存放所有策略类Bean的map |
6 | public static Map<Class<?>, Map<String, Class<?>>> conversionFactoryMap = new ConcurrentHashMap<>(); |
7 | |
8 | /** |
9 | * 获取对应的类对象 |
10 | * |
11 | * @param type 类型 |
12 | * @param interfaceClass 接口类反射 |
13 | * @return 返回一个类对象 |
14 | * @throws IllegalAccessException 没有访问权限 |
15 | * @throws InstantiationException 实例化异常 |
16 | */ |
17 | public T getResult(String type, Class<?> interfaceClass) throws IllegalAccessException, InstantiationException { |
18 | // 打印在Map中的存在的数据 |
19 | log.debug("缓存中的数据,一共有 >>>>>>> {}", conversionFactoryMap.toString()); |
20 | // 获取接口归类 |
21 | Map<String, Class<?>> classMap = conversionFactoryMap.get(interfaceClass); |
22 | // 获取对应的对象,并强转成自己的类 |
23 | Class<T> zclass = (Class<T>) classMap.get(type); |
24 | if (zclass == null) { |
25 | throw new IllegalArgumentException("没有对应的类型"); |
26 | } |
27 | //从容器中获取对应的策略Bean |
28 | log.info("转换后的类属性为 >>>> {}", zclass.newInstance()); |
29 | return zclass.newInstance(); |
30 | } |
31 | |
32 | } |
1.7 编写Controller(控制器)测试
1 | |
2 | 4j |
3 | public class StrategyController { |
4 | |
5 | /** |
6 | * 传入想拿的service的名称后,sevice放回一个对应的service |
7 | * @param key 想拿的service名称 |
8 | * @return |
9 | */ |
10 | ("/strategy") |
11 | |
12 | public String strategy(@RequestParam("key") String key) { |
13 | String result; |
14 | try { |
15 | ConversionFactory<Strategy> conversionFactory = new ConversionFactory<>(); |
16 | result = conversionFactory.getResult(key, Strategy.class).doOperation(); |
17 | } catch (Exception e) { |
18 | e.printStackTrace(); |
19 | result = e.getMessage(); |
20 | } |
21 | return result; |
22 | } |
23 | |
24 | } |
注:pom文件
本文使用SpringBoot的版本为
1 | <dependencies> |
2 | <dependency> |
3 | <groupId>org.springframework.boot</groupId> |
4 | <artifactId>spring-boot-starter-web</artifactId> |
5 | </dependency> |
6 | |
7 | <dependency> |
8 | <groupId>org.springframework.boot</groupId> |
9 | <artifactId>spring-boot-devtools</artifactId> |
10 | <scope>runtime</scope> |
11 | <optional>true</optional> |
12 | </dependency> |
13 | <dependency> |
14 | <groupId>org.projectlombok</groupId> |
15 | <artifactId>lombok</artifactId> |
16 | <optional>true</optional> |
17 | </dependency> |
18 | <dependency> |
19 | <groupId>org.springframework.boot</groupId> |
20 | <artifactId>spring-boot-starter-test</artifactId> |
21 | <scope>test</scope> |
22 | <exclusions> |
23 | <exclusion> |
24 | <groupId>org.junit.vintage</groupId> |
25 | <artifactId>junit-vintage-engine</artifactId> |
26 | </exclusion> |
27 | </exclusions> |
28 | </dependency> |
29 | </dependencies> |