目录
前言
五个部分
名词解释
代码
controller层
HelloService接口
实现类
自定义注解
上下文
策略工厂
Java SPI配置
验证
前言
五个部分
接口、实现类、自定义注解、上下文、策略工厂
名词解释
自定义注解(方便后期增加实现类后灵活控制策略)
上下文(初始化接口,进行数据承接)
策略工厂(利用java SPI使接口与实现解耦,并通过验证注解是否存在,调用不同的策略)
代码
controller层
package com.zsp.sheji.JavaSPI;import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("hello")
public class HelloController {@PostMapping("/pay")public String pay(){PayContext payContext = new PayContext();payContext.setHelloService(PayFactory.makeHello("helloOne"));String result = payContext.sayHello("你好");return result;}
}
HelloService接口
package com.zsp.sheji.JavaSPI;public interface HelloService {String sayHello(String hello);
}
实现类
这里写了两个实现类,模拟真实环境中的不同策略调用
HelloOneServiceImpl
package com.zsp.sheji.JavaSPI;import org.springframework.stereotype.Service;@Pay(type = "helloOne")
@Service
public class HelloOneServiceImpl implements HelloService{@Overridepublic String sayHello(String hello) {return hello + "=== one";}
}
HelloTwoServiceImpl
package com.zsp.sheji.JavaSPI;import org.springframework.stereotype.Service;@Pay(type = "helloTwo")
@Service
public class HelloTwoServiceImpl implements HelloService{@Overridepublic String sayHello(String hello) {return hello + "=== two";}
}
自定义注解
package com.zsp.sheji.JavaSPI;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pay {String type();
}
上下文
package com.zsp.sheji.JavaSPI;import org.springframework.stereotype.Component;@Component
public class PayContext {private HelloService helloService;public void setHelloService(HelloService helloService){this.helloService = helloService;}public PayContext(){}public String sayHello(String hello){// 上下文进行数据承接return this.helloService.sayHello(hello);}
}
策略工厂
package com.zsp.sheji.JavaSPI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;public class PayFactory {private static Map<String,HelloService> helloMap = new HashMap<>();static {ServiceLoader<HelloService> load = ServiceLoader.load(HelloService.class);Iterator<HelloService> iterator = load.iterator();while (iterator.hasNext()) {HelloService next = iterator.next();Class<? extends HelloService> aClass = next.getClass();if (!aClass.isAnnotationPresent(com.zsp.sheji.JavaSPI.Pay.class)) {// 不存在添加进去throw new IllegalStateException("class: " + aClass + " expect @com.zsp.sheji.策略模式高级注解方式.PayType, but not found!");}helloMap.put(aClass.getAnnotation(Pay.class).type(), next);}}public static HelloService makeHello(String type){return helloMap.get(type);}
}
Java SPI配置
文件名:com.zsp.sheji.JavaSPI.HelloService 对应接口的全限定类名
com.zsp.sheji.JavaSPI.HelloOneServiceImpl
com.zsp.sheji.JavaSPI.HelloTwoServiceImpl
项目结构