栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot中使用AOP+发布订阅实现功能模块解耦

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot中使用AOP+发布订阅实现功能模块解耦

业务场景:开发一个计算接口,接口需要从FTP中下载报表文件进行解析,返回计算数据,同时生成检测报告上传至指定ftp。
此业务中包含以下几个动作:
1.登录FTP下载文件到本地;
2.解析文件;
3.生成自检报告并上传到指定ftp,并以邮件形式通知客户;
4.重置服务本地文件夹信息,防止数据混乱.
5.返回解析数据结果;

最初版本是线性同步作业:1—>2—>3—>4—>5,正常情况下除了接口响应速度慢,功能基本没有问题,但是在邮件发送或重置文件夹信息抛出异常时,接口无法正常返回数据;
版本2,将自检报告上传、邮件发送、重置文件夹信息提交到线程池,进行异步执行,提高了接口响应速度,解决了邮件发送或重置文件夹信息抛出异常时,接口无法正常返回数据的问题。但是实际生产中出现了因文件格式异常产生计算错误,导致服务抛出异常,第4步重置文件夹动作未执行,后续再次请求时数据混乱的问题;
版本3:使用自定义注解,配合AOP,在接口执行后拦截(后置通知增强),当方法执行完后(无论是否抛出异常都会执行),发布自定义计算完成事件,在监听器中执行重置本地文件夹方法,这样解耦更彻底,即使计算方法出错,文件夹相关信息也会被清除,不会造成下一次计算数据混乱。
1.自定义注解

package com.weige.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) // 表示该注解只能用来修饰在方法上
public @interface initFileInfo {
    Class businessType() default Object.class;//类类型属性
    String value() default "重置文件信息";
}

2.切面配置

package com.weige.aspect;



import com.weige.config.SBLCompleteEvent;

import com.weige.vo.SBLRequestParam;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;



@Aspect
@Component
public class InitFileInfoAspect {
    Logger logger = LoggerFactory.getLogger(InitFileInfoAspect.class);
    @Autowired
    ApplicationContext applicationContext;
    //定义切点
    @Pointcut("execution(public * com.weige.controller.*.*(..))")
    public void webLog(){}


    @Before("webLog()")
    public void deBefore(JoinPoint joinPoint) throws Throwable {
      

    }

 

    //后置异常通知
    @AfterThrowing("webLog()")
    public void throwss(JoinPoint jp){

//        System.out.println("方法异常时执行啦,.....");
    }

    //这里使用后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
    @After("webLog()")
    public void after(JoinPoint jp){
        Object obj=jp.getArgs()[0];
        if(obj instanceof SBLRequestParam){
            SBLRequestParam sblRequestParam=(SBLRequestParam)obj;
            String lotid=sblRequestParam.getLotId();
            //事件发布(如果不配置异步支持,流程会阻塞到这里,
            //监听事件完成后流程才会往下走)
            applicationContext.publishEvent(new SBLCompleteEvent(this, lotid));
        }



    }


}

3.自定义事件

package com.weige.config;

import org.springframework.context.ApplicationEvent;


public class SBLCompleteEvent extends ApplicationEvent {
    private String lotId;

    public String getLotId() {
        return lotId;
    }

    public void setLotId(String lotId) {
        this.lotId = lotId;
    }

    public SBLCompleteEvent(Object source,String lotId) {
        super(source);
        this.setLotId(lotId);
    }
}

4.自定义监听器,监听指定事件

package com.weige.config;

import com.weige.service.business.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.File;
import java.lang.reflect.InvocationTargetException;





@Component
@Async
public class SblCompleteListener {
    @Value("${localDirPath}")
    private  String localDirPath;

    @Autowired
    FileService fileService;



    @EventListener
    @Order(1)
    public void initDir(SBLCompleteEvent sblCompleteEvent) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        System.out.println("我监听到SBLP计算完了,准备删除对应文件:"+sblCompleteEvent.getLotId());
        // 获取注册用户对象
        String lotId = sblCompleteEvent.getLotId();
        //执行删除动作
        fileService.deleteFile(new File(localDirPath),lotId);
        System.out.println("终于删除成功了。。。。");

    }


}

以上是工作过程中处理问题的一些思路,特此记录。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786055.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号