目录
前言
五个部分
名词解释
代码
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{
@Override
public 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{
@Override
public 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
项目结构