大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说如何写业务代码_业务员代码是什么意思,希望您对编程的造诣更进一步.
前言
在我们开发过程中,会经常碰到这么一些需求,比如在在主流程执行前,要做一些前置事件,在主流程执行之后,做一些收尾工作。对一些新手程序员,他可能会直接写类似如下的代码
public void execute(){
doBefore();
doBiz();
doAfter();
}
复制代码
对有一定工作经验的程序员,他可能会用AOP或者用一些设计模式比如模板模式。那我们今天来聊聊下使用spring + spi + aop + 责任链来实现上面的需求
代码实现过程分析
假设主流程只需做一次前置处理和一次后置处理,则伪代码如下
public void execute(){
doBefore();
doBiz();
doAfter();
}
复制代码
此时我们可以用模板模式或者AOP,这边我们采用AOP。其伪代码如下
public class CorMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
doBefore();
Object result = invocation.proceed();
return result;
} catch (Throwable throwable) {
log.error("{}",e);
} finally {
doAfter();
}
return null
}
}
复制代码
如果对这种写法不适应,可以采用@Aspect + @Around方式,效果一个样。
当主流程需要多次前置处理和多次后置处理时,我们的代码可能就变成
public class CorMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
doBefore();
doBefore();
doBefore();
....
Object result = invocation.proceed();
return result;
} catch (Throwable throwable) {
log.error("{}",e);
} finally {
doAfter();
doAfter();
doAfter();
...
}
return null
}
}
复制代码
此时这些前置处理或者后置处理看起来就像是一条链,于是我们就可以考虑采用一些设计模式比如责任链或者采用管道模式。本示例我们使用责任链模式
代码实现
1、创建处理器接口
public interface AbstarctHandler extends Ordered {
/**
* 预处理回调,实现服务的预处理
* @return true表示流程继续,false表示流程中断,不会继续调用其他处理器或者服务
*/
default boolean preHandler(Invocation invocation){
return true;
}
/**
* 整个请求处理完毕回调方法。类似try-catch-finally中的finally。多个afterCompletion按倒叙输出
*/
default void afterCompletion(Invocation invocation){}
}
复制代码
2、创建处理器链
public class MethodInterceptorChain {
private final List<AbstarctHandler> abstarctHandlers = new ArrayList<>();
public void addHandler(AbstarctHandler handler){
abstarctHandlers.add(handler);
}
public List<AbstarctHandler> getHanlders(){
if(CollectionUtils.isEmpty(abstarctHandlers)){
return Collections.emptyList();
}
AnnotationAwareOrderComparator.sort(abstarctHandlers);
return Collections.unmodifiableList(abstarctHandlers);
}
}
复制代码
3、业务逻辑和责任链整合
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CorHandlerInterceptor {
private MethodInterceptorChain chain;
public Object invoke(Invocation invocation) throws Exception {
List<AbstarctHandler> abstarctHandlers = chain.getHanlders();
if(CollectionUtils.isEmpty(abstarctHandlers)){
invocation.invoke();
}
boolean isCanExec = true;
int canExecCount = 0;
for (AbstarctHandler abstarctHandler : abstarctHandlers) {
canExecCount++;
if(!abstarctHandler.preHandler(invocation)){
isCanExec = false;
break;
}
}
try{
if(isCanExec){
return invocation.invoke();
}
}catch (Exception e){
throw new Exception(e);
}finally {
for (int i = 0; i < canExecCount; i++) {
int j = canExecCount - i - 1;
abstarctHandlers.get(j).afterCompletion(invocation);
}
}
return null;
}
}
复制代码
4、创建AOP切面
public class CorMethodInterceptor implements MethodInterceptor {
private CorHandlerInterceptor corHandlerInterceptor;
public CorMethodInterceptor(CorHandlerInterceptor corHandlerInterceptor) {
this.corHandlerInterceptor = corHandlerInterceptor;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Invocation invoker = Invocation.builder()
.args(invocation.getArguments())
.method(invocation.getMethod())
.target(invocation.getThis()).build();
return corHandlerInterceptor.invoke(invoker);
}
}
复制代码
5、配置切点
@Bean
@ConditionalOnMissingBean
public AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor(PointcutProperites pointcutProperites, CorHandlerInterceptor corHandlerInterceptor){
AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
aspectJExpressionPointcutAdvisor.setExpression(pointcutProperites.getExpression());
aspectJExpressionPointcutAdvisor.setAdvice(new CorMethodInterceptor(corHandlerInterceptor));
return aspectJExpressionPointcutAdvisor;
}
复制代码
6、处理器注入spring
@Bean
@ConditionalOnMissingBean
public CorHandlerInterceptor corHandlerInterceptor(ObjectProvider<List<AbstarctHandler>> provider){
MethodInterceptorChain methodInterceptorChain = new MethodInterceptorChain();
loadedHandlerBySpring(provider, methodInterceptorChain);
loadedHanlderBySpi(methodInterceptorChain);
CorHandlerInterceptor corHandlerInterceptor = new CorHandlerInterceptor();
corHandlerInterceptor.setChain(methodInterceptorChain);
return corHandlerInterceptor;
}
@Bean
@ConditionalOnMissingBean
public DefaultHandler defaultHandler(){
return new DefaultHandler();
}
private void loadedHanlderBySpi(MethodInterceptorChain methodInterceptorChain) {
ServiceLoader<AbstarctHandler> serviceLoader = ServiceLoader.load(AbstarctHandler.class);
Iterator<AbstarctHandler> iterator = serviceLoader.iterator();
while(iterator.hasNext()){
AbstarctHandler abstarctHandler = iterator.next();
log.info("load hander by spi -> 【{}】",abstarctHandler.getClass().getName());
methodInterceptorChain.addHandler(abstarctHandler);
}
}
private void loadedHandlerBySpring(ObjectProvider<List<AbstarctHandler>> provider, MethodInterceptorChain methodInterceptorChain) {
List<AbstarctHandler> getListBySpring = provider.getIfAvailable();
if(!CollectionUtils.isEmpty(getListBySpring)){
for (AbstarctHandler abstarctHandler : getListBySpring) {
log.info("load hander by spring -> 【{}】",abstarctHandler.getClass().getName());
methodInterceptorChain.addHandler(abstarctHandler);
}
}
}
复制代码
示例演示
1、编写业务服务
public interface HelloService {
String sayHello(String username);
}
复制代码
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String username) {
return "hello : " + username;
}
}
复制代码
2、编写处理器
一种通过@Component
@Component
public class HelloServiceNameInterceptor implements AbstarctHandler {
@Override
public boolean preHandler(Invocation invocation) {
Object[] args = invocation.getArgs();
System.out.println("名称校验-->preHandler");
for (Object arg : args) {
if("张三".equals(arg)){
return false;
}
}
return true;
}
@Override
public void afterCompletion(Invocation invocation) {
System.out.println("名称校验-->afterCompletion:" + Arrays.toString(invocation.getArgs()));
}
@Override
public int getOrder() {
return 102;
}
}
复制代码
一种通过SPI
public class HelloServiceSpiInterceptor implements AbstarctHandler {
@Override
public boolean preHandler(Invocation invocation) {
Object[] args = invocation.getArgs();
System.out.println("参数转换-->preHandler");
for (int i = 0; i < args.length; i++) {
if("lisi".equals(args[i])){
args[i] = "李四";
}
}
return true;
}
@Override
public void afterCompletion(Invocation invocation) {
System.out.println("参数转换-->afterCompletion:" + Arrays.toString(invocation.getArgs()));
}
@Override
public int getOrder() {
return -1;
}
}
复制代码
配置SPI
内容如下
com.github.lybgeek.cor.test.interceptor.HelloServiceSpiInterceptor
复制代码
3、配置切点表达式
lybgeek:
pointcut:
expression: execution(* com.github.lybgeek.cor.test.service..*.*(..))
复制代码
4、测试
观察控制台
发现处理器正常工作
总结
所谓的可扩展,指在新增功能时,不需要或者少修改原有的功能。用设计原则来讲就是对修改关闭,对扩展开放。本文的示例如果心细的朋友就会发现,这跟springmvc的拦截器实现是很像的
作者:linyb极客之路
链接:https://juejin.cn/post/7080330791423016990
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/11761.html