动态初始化类+参数泛型化+统一返回值
目录
学习了《动态初始化类 InitializingBean》,结合泛化参数一起使用,这样就更完整些,实际使用中还缺少了返回值和异常的处理,这次一并添加上。逐步添加,便于理解,循序渐进。
添加的类
返回值:
CircleResult
@Data
@ToString
@ApiModel(value = "圆形结果")
public class CircleResult {
@ApiModelProperty("半径")
private String radius;
@ApiModelProperty("颜色")
private String color;
}
统一返回值:
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import java.io.Serializable;
/**
* @param <T>
*/
@Data
@Builder(toBuilder = true)
@ToString
public class ShapeResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
@Builder.ObtainVia(method = "success")
private boolean success;
private Integer code;
private String msg;
private String detail;
private T data;
private boolean success() {
if (success) {
if (code == null) {
this.code = ShapeException.SUCCESS_CODE;
}
} else {
if (code == null) {
this.code = ShapeException.ERROR_CODE;
}
}
return success;
}
}
异常类:ShapeException
public class ShapeException extends RuntimeException {
public static final Integer SUCCESS_CODE = 200;
public static final Integer ERROR_CODE = 500;
/**
* 错误码
*/
private Integer code;
private Object data;
public ShapeException(Integer code, String message) {
this(code, message, null, null);
}
public ShapeException(String message) {
super(message);
}
public ShapeException(String message, Throwable cause) {
super(message, cause);
}
public ShapeException(Integer code, String message, Object data, Throwable cause) {
super(message, cause);
this.code = code;
this.data = data;
}
public Integer getCode() {
return code;
}
public Object getData() {
return data;
}
}
返回值处理和异常:
/**
* @param <I>
* @param <O>
*/
@Slf4j
public abstract class ReturnShapeFunc<I, O> extends AbstractShapeFunc<I, O> {
@Override
protected ShapeResult<O> buildResult(ShapeRequest<I> flowAppRequest, O resultData) {
return ShapeResult.<O>builder().success(true).build().toBuilder().data(resultData)
.build();
}
@Override
protected ShapeResult<O> handleException(ShapeRequest<I> flowAppRequest, Throwable ex) {
log.error("调用异常! 请求参数: {}", flowAppRequest, ex);
if (ex instanceof ShapeException) {
ShapeException appException = (ShapeException) ex;
// 处理可能有返回值的情况
return ShapeResult.<O>builder().success(false).code(appException.getCode()).build().toBuilder()
.msg(appException.getMessage()).detail(ExceptionUtils.getStackTrace(ex))
.data(appException.getData() == null ? null : (O) appException.getData()).build();
} else {
return ShapeResult.<O>builder().success(false).build().toBuilder()
.msg(ex.getMessage()).detail(ExceptionUtils.getStackTrace(ex)).build();
}
}
}
不变的接口:
ShapeFactory
GenericUtils
变化的类:
代码:
Shape接口:
/**
* @param <I> 入参类型
* @param <O> 出参类型
*/
public interface ShapeFunc<I, O> {
ShapeResult<O> execute(ShapeRequest<I> shapeRequest);
}
AbstractShapeFunc
@Slf4j
public abstract class AbstractShapeFunc<I,O> implements ShapeFunc<I,O>, InitializingBean {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Override
public ShapeResult<O> execute(ShapeRequest<I> shapeRequest) {
try {
I param = exchangeParam(shapeRequest.getParam());
O resultData = doExecute(param);
return buildResult(shapeRequest, resultData);
} catch (Throwable ex) {
return handleException(shapeRequest, ex);
}
}
protected abstract O doExecute(I requestParam);
protected abstract ShapeResult<O> buildResult(ShapeRequest<I> shapeRequest, O resultData);
protected abstract ShapeResult<O> handleException(ShapeRequest<I> shapeRequest, Throwable ex);
private I exchangeParam(Object data) throws IOException {
Class requestGenricType = GenericUtils.getSuperClassGenricType(getClass(), 0);
if (!Map.class.isAssignableFrom(requestGenricType)) {
return (I) MAPPER.readValue(MAPPER.writeValueAsString(data), requestGenricType);
}
return (I) data;
}
protected abstract String supportType();
@Override
public void afterPropertiesSet(){
ShapeFactory.getInstance().register(supportType(), this);
}
}
添加了返回值和异常的处理。这样就变得完整一些
CircleService
@Component
public class CircleService extends ReturnShapeFunc<CircleRequest, CircleResult> {
@Override
protected CircleResult doExecute(CircleRequest requestParam) {
System.out.println("圆形: "+requestParam.getColor() + requestParam.getRadius());
CircleResult circleResult = new CircleResult();
circleResult.setColor("blue");
circleResult.setRadius("12.55f");
return circleResult;
}
@Override
protected String supportType() {
return "circle";
}
}
RectangleService
@Component
public class RectangleService extends ReturnShapeFunc<Map<String,Object>, Map<String,Object>> {
@Override
protected Map<String,Object> doExecute(Map<String,Object> requestParam){
System.out.println("正方形: "+requestParam.get("rec"));
Map<String,Object> result = new HashMap<>();
result.put("test", "do");
result.put("ip", "122");
return result;
}
@Override
protected String supportType() {
return "rectangle";
}
}
TriangleService
@Component
public class TriangleService extends ReturnShapeFunc<List<Map<String,Object>>, Integer> {
@Override
protected Integer doExecute(List<Map<String, Object>> requestParam){
System.out.println("三角形:"+requestParam.toString());
return 66;
}
@Override
protected String supportType() {
return "triangle";
}
}
TrapezoidService
@Component
public class TrapezoidService extends ReturnShapeFunc<String,String> {
@Override
protected String doExecute(String requestParam) {
System.out.println("梯形: "+requestParam);
return "返回一个梯形啦";
}
@Override
protected String supportType() {
return "trapezoid";
}
}
ShapeFuncsService
@Service
public class ShapeFuncsService {
public ShapeResult execute(ShapeRequest shapeRequest) throws Exception {
return ShapeFactory.getInstance().getShape(shapeRequest.getType()).execute(shapeRequest);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class TestBeanInitAdd {
@Resource
private ShapeFuncsService shapeFuncsService;
@Test
public void testInit2() throws Exception {
ShapeRequest shapeRequest = new ShapeRequest();
shapeRequest.setType("circle");
CircleRequest circleRequest = new CircleRequest();
circleRequest.setColor("blue");
circleRequest.setRadius("12.22f");
shapeRequest.setParam(circleRequest);
ShapeResult execute = shapeFuncsService.execute(shapeRequest);
System.out.println("circle: "+ execute.toString());
shapeRequest = new ShapeRequest();
shapeRequest.setType("rectangle");
Map<String,Object> single = new HashMap<>();
single.put("rec","yan");
shapeRequest.setParam(single);
execute = shapeFuncsService.execute(shapeRequest);
System.out.println("rectangle: "+ execute.toString());
shapeRequest = new ShapeRequest();
shapeRequest.setType("triangle");
List<Map<String,Object>> singles = new ArrayList<>();
single.put("dream","do things well");
singles.add(single);
shapeRequest.setParam(singles);
execute = shapeFuncsService.execute(shapeRequest);
System.out.println("triangle: "+ execute.toString());
shapeRequest = new ShapeRequest();
shapeRequest.setType("trapezoid");
shapeRequest.setParam("画一个梯形");
execute = shapeFuncsService.execute(shapeRequest);
System.out.println("trapezoid: "+ execute.toString());
}
}
结果:
圆形: blue12.22f
circle: ShapeResult(success=true, code=200, msg=null, detail=null, data=CircleResult(radius=12.55f, color=blue))
正方形: yan
rectangle: ShapeResult(success=true, code=200, msg=null, detail=null, data={test=do, ip=122})
三角形:[{rec=yan, dream=do things well}]
triangle: ShapeResult(success=true, code=200, msg=null, detail=null, data=66)
梯形: 画一个梯形
trapezoid: ShapeResult(success=true, code=200, msg=null, detail=null, data=返回一个梯形啦)
总结:
加上返回的拼接和异常的处理,这样就变得完整些了,实用性也比较好。