Filter过滤器学习使用

验证token

对外API过滤器
public class APIFilter implements Filter {
   
    private static Logger logger = LogManager.getLogger(APIFilter.class);
    private ICachedTokenService tokenService;

    public APIFilter(ICachedTokenService tokenService) {
   
        super();
        this.tokenService = tokenService;
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
   

    }
    @Override
    public void destroy() {
   

    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
   
        HttpServletRequest hreq = (HttpServletRequest) req;
        HttpServletResponse hres = (HttpServletResponse) resp;
		//设置一些Header其他信息
        hres.setHeader("Access-Control-Allow-Origin", hreq.getHeader("Origin"));
        hres.setHeader("Access-Control-Allow-Credentials", "true");
        hres.setHeader("Access-Control-Allow-Methods", hreq.getMethod());
        hres.setHeader("Access-Control-Max-Age", "86400");
        hres.setHeader("Access-Control-Allow-Headers", "*");
       
        //不校验权限
        if(hreq.getRequestURI().contains("/unauth") || hreq.getRequestURI().contains("/question")){
   
            chain.doFilter(req, resp);
            return;
        }

        // 如果是OPTIONS则结束请求
        if (HttpMethod.OPTIONS.toString().equals(hreq.getMethod())) {
   
            hres.setStatus(HttpStatus.NO_CONTENT.value());
            return;
        }
        
        try{
   
        	//从请求cookie中获取access_token
            AccessTokenUser user = null;
            String access_token=hreq.getParameter("access_token");
            if(StringUtils.isBlank(access_token)){
   
                access_token= hreq.getHeader("access_token");
            }
            if(StringUtils.isBlank(access_token)){
   
                access_token=this.getCookieByCookieName("access_token", hreq);
            }
            //获取用户
            if(StringUtils.isNotBlank(access_token)){
   
                String token=access_token;
                user = ThreadLocalCache.fetchAPIData(
                    "AccessTokenUserByAccessToken:"+token+",true",
                    () -> {
   
                        ApiResultDTO<AccessTokenUser> tokenUserResp= tokenService.getAccessTokenUserByAccessToken(token, true);
                        if(tokenUserResp.isSuccessed()) {
   
                            return tokenUserResp;
                        }else {
   
                            String errorMsg = "访问令牌服务发生错误,错误码:"+tokenUserResp.getStatus()+",错误信息:"+tokenUserResp.getStatusMsg();
                            logger.error(errorMsg);
                            throw new RuntimeException(errorMsg);
                        }
                    }
                );
                //判断是否存在这样的用户
                if(user==null) logger.error("请求地址{}根据access_token【{}】无法获取登录用户。",hreq.getRequestURI(),access_token);
            }
            
            if(user==null){
   
                throw new BusinessException("登录已过期,请重新登录!", ApiResultDTO.STATUS_UNAUTH);
            }
            
            LoginInitUtils.afterLogin(false,hreq,hres,user);
            
            chain.doFilter(req, resp);
            return;
        } catch (Exception e) {
   
            ApiResultDTO<String> apiResult=null;
            if(e instanceof BusinessException) {
   
                BusinessException businessException = (BusinessException) e;
                apiResult = ApiResultDTO.failed(businessException.getErrorCode(), businessException.getOriMsg());
            }else {
   
                apiResult = ApiResultDTO.failed(e.getMessage());
            }
             hres.setContentType("application/json;charset=UTF-8");
             hres.setHeader("Cache-Control", "no-store");
             hres.setHeader("Pragma", "no-cache");
             hres.setDateHeader("Expires", 0);
             hres.getWriter().write(new ObjectMapper().writeValueAsString(apiResult));
             hres.getWriter().flush();
             hres.getWriter().close();
        }
    }
    
    private String getCookieByCookieName(String cookieName,HttpServletRequest hreq) {
   
        Cookie[] cookies = hreq.getCookies();
        if(cookies!=null){
   
            for(Cookie cookie:cookies){
   
                if(cookieName.equalsIgnoreCase(cookie.getName())){
   
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
}
对内API过滤器
public class _APIFilter implements Filter {
   
	private Logger logger=LogManager.getLogger(this.getClass()); 
	
    private ICachedTokenService tokenService;
    
    public _APIFilter(ICachedTokenService tokenService) {
   
        super();
        this.tokenService = tokenService;
    }
    
    @Override
    public void init(FilterConfig arg0) throws ServletException {
   
        
    }
    @Override
    public void destroy() {
   
    	
    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
   
    	HttpServletRequest hreq = (HttpServletRequest) req;
    	HttpServletResponse hres = (HttpServletResponse) resp;
        try{
   
            Utils.passOverByIp(hreq.getRemoteAddr());
            
           // logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]开始--------------------------");
            AccessTokenUser user = null;
            String access_token=hreq.getParameter("access_token");
            if(StringUtils.isBlank(access_token)){
   
                access_token= hreq.getHeader("access_token");
            }
            //根据访问令牌获取用户
            if(StringUtils.isNotBlank(access_token)){
   
                try {
   
                    String token=access_token;
                    user = ThreadLocalCache.fetchAPIData(
                        "AccessTokenUser."+token+",true",
                        () -> {
   
                        	ApiResultDTO<AccessTokenUser> tokenUserResp=  tokenService.getAccessTokenUserByAccessToken(token, true);
                            if(tokenUserResp.isSuccessed()) {
   
                        		return tokenUserResp;
                        	}else {
   
                        		String errorMsg = "访问令牌服务发生错误,错误码:"+tokenUserResp.getStatus()+",错误信息:"+tokenUserResp.getStatusMsg();
                        		logger.error(errorMsg);
                        		throw new RuntimeException(errorMsg);
                        	}
                        }
                    );
                } catch (Exception e) {
   
                    e.printStackTrace();
                    user=null;
                }
                if(user==null) logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]access_token["+access_token+"]获取用户结果"+user+"--------------------------");
            }
            //根据内部令牌获取用户
            if(user==null) {
   
            	String inner_token=hreq.getParameter("inner_token");
                if(StringUtils.isBlank(inner_token)){
   
                    inner_token = hreq.getHeader("inner_token");
                }
                if(StringUtils.isBlank(inner_token)) throw new RuntimeException("未找到访问令牌");
                
                String token=inner_token;
                user=ThreadLocalCache.fetchAPIData(null,()->{
   
                    return tokenService.verifyTokenAndGetUser(token);
                },"验证访问令牌错误,");
                if(user==null) logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]inner_token["+inner_token+"]获取用户结果"+user+"--------------------------");
            }
            
            LoginInitUtils.afterLogin(false,hreq,hres,user);
            
            chain.doFilter(req, resp);
            return;
        } catch (Exception e) {
   
        	e.printStackTrace();
        	ApiResultDTO<String> apiResult=ApiResultDTO.failed(e.getMessage());
            hres.setContentType("application/json;charset=UTF-8");
            hres.setHeader("Cache-Control", "no-store");
            hres.setHeader("Pragma", "no-cache");
            hres.setDateHeader("Expires", 0);
            hres.getWriter().write(new ObjectMapper().writeValueAsString(apiResult));
            hres.getWriter().flush();
            hres.getWriter().close();
		}
    }
    
}
public ApiResultDTO<AccessTokenUser> verifyTokenAndGetUser(String inner_token) {
   
        Map<String,String> claims=JWTUtils.verifyTokenAndGetClaims(inner_token);
        AccessTokenUser user=null;
        if(claims.get("user")!=null) {
   
            user=JsonConverter.jsonStrToObject(claims.get("user"), AccessTokenUser.class);
        }
        return ApiResultDTO.success(user);
        
    }
//将inner_token 转化为用户信息
public static Map<String,String> verifyTokenAndGetClaims(String jwt_token) {
   
		JWT jwt=JWT.create();
        //jwt.setHeader(JWTHeader.TYPE, "JWT");//默认值
        jwt.setHeader(JWTHeader.ALGORITHM, "HS256");
        jwt.setSigner(JWTSignerUtil.createSigner("HS256", SECRET));
	    try {
   
	        jwt.parse(jwt_token);
		} catch (Exception e) {
   
            e.printStackTrace();
            throw new RuntimeException("校验jwt_token令牌失败");
        }
	    if(!jwt.verify()) {
   
        	throw new RuntimeException("无效的jwt_token");
        }
        
    	Map<String,String> result = new HashMap<String,String>();
    	
    	JSONObject jo=jwt.getPayloads();
    	if(jo==null||jo.size()==0) {
   
    		return result;
    	}
        for (Map.Entry<String,Object> d: jo.entrySet()) {
   
        	if(d.getValue()==null) {
   
        		continue;
        	}
        	result.put(d.getKey(), d.getValue().toString());
		}
        
        return result;
	}

配置拦截器

@Configuration
public class FiltersConfiguration {
   
    @Autowired
    private ICachedTokenService tokenService;
    
    //前后端交互处理-拦截所有api访问请求
    @Bean
    public FilterRegistrationBean<APIFilter> apiFilterRegistrationBean() {
   
        FilterRegistrationBean<APIFilter> registrationBean = new FilterRegistrationBean<APIFilter>();
        registrationBean.setFilter(new APIFilter(tokenService));
        registrationBean.addUrlPatterns("/api/*");
        registrationBean.setOrder(5);
        return registrationBean;
    }
    
    //前后端交互处理-拦截所有_api访问请求
    @Bean
    public FilterRegistrationBean<_APIFilter> _apiFilterRegistrationBean() {
   
        FilterRegistrationBean<_APIFilter> registrationBean = new FilterRegistrationBean<_APIFilter>();
        registrationBean.setFilter(new _APIFilter(tokenService));
        registrationBean.addUrlPatterns("/_api/*");
        registrationBean.setOrder(6);
        return registrationBean;
    }
}

清除缓存

基础数据定义的一些资源变更,需要同步清除其他项目本地缓存

配置清除缓存过滤器
	//处理基础数据变更后通知各系统清空本系统的基础数据的缓存
    @Bean
    public FilterRegistrationBean<FireSysDataChangedEventFilter> fireSysDataChangedEventFilterRegistrationBean() {
   
        FilterRegistrationBean<FireSysDataChangedEventFilter> registrationBean = new FilterRegistrationBean<FireSysDataChangedEventFilter>();
        registrationBean.setFilter(new FireSysDataChangedEventFilter(fireSysDataChangedEventService));
        registrationBean.addUrlPatterns("/api/*");
        registrationBean.setOrder(5);
        return registrationBean;
    }
定义过滤器
public class FireSysDataChangedEventFilter implements Filter {
   
	private Logger logger = LoggerFactory.getLogger(this.getClass());
    private IFireSysDataChangedEventService fireSysDataChangedEventService;

    public FireSysDataChangedEventFilter(IFireSysDataChangedEventService fireSysDataChangedEventService) {
   
        super();
        this.fireSysDataChangedEventService = fireSysDataChangedEventService;
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
   

    }
    @Override
    public void destroy() {
   

    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
   
    	try {
   
    		chain.doFilter(req, resp);
    		fireSysDataChangedEventIfNecessary(req);
    	}finally {
   
    		SysDataChanged.reset();
    	}
    }

	private void fireSysDataChangedEventIfNecessary(ServletRequest req) {
   
		try {
   
			if(SysDataChanged.isChanged()) {
   
				HttpServletRequest hreq = (HttpServletRequest)req;
				String uri = hreq.getRequestURI();
				logger.info("完成请求{}后,基础数据有变更,需要向其他系统发出清除缓存的消息",uri);
				fireSysDataChangedEventService.sysDataChanged();
			}
		}catch(Exception e) {
   
			e.printStackTrace();
			logger.error("fireSysDataChangedEventIfNecessary错误{}",e.getMessage());
		}	
	}
}
定义清除缓存服务
public interface IFireSysDataChangedEventService {
   
	/**
	 * 基础数据发生变更
	 */
	void sysDataChanged();

}
@Service
@ConfigurationProperties(prefix="docin-sys.config",ignoreUnknownFields=true)
public class FireSysDataChangedEventService implements IFireSysDataChangedEventService  {
   
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private ISysDataVersionService sysDataVersionService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private AsyncTaskComponent asyncTaskComponent;
    //这里的url是再配置文件配置的
    //清理缓存urls
    private Map<String, List<String>> clearcacheurls = new HashMap<>();
    public void setClearcacheurls(Map<String, List<String>> clearcacheurls) {
   
        this.clearcacheurls = clearcacheurls;
    }
    
    
    @SuppressWarnings("unchecked")
    @Override
    public void sysDataChanged() {
   
        long lastTimestamp = System.currentTimeMillis();
        //更新系统版本时间戳
        sysDataVersionService.updateLastTimestampOfSysData(lastTimestamp);
        logger.info("成功更新系统版本时间戳为{}",lastTimestamp);
        if(MapUtils.isEmpty(clearcacheurls)) return;
        for (Map.Entry<String,List<String>> e: clearcacheurls.entrySet()) {
   
            asyncTaskComponent.runTaskInThreadPool((d)->{
   
                String name=(String)d.get("name");
                List<String> urls=(List<String>)(d.get("urls"));
                for (String url : urls) {
   
                    try {
   
                        restTemplate.getForObject(url, String.class);
                        logger.info("向服务["+name+"].["+url+"]发送清理缓存请求成功");
                    } catch (Exception e2) {
   
                        logger.error("向服务["+name+"].["+url+"]发送清理缓存请求失败,",e2);
                    }
                }
                return null;
            }, Utils.buildMap("name",e.getKey(),"urls",e.getValue()));
        }
    }
    
}
docin-sys.config.clearcacheurls.docin-xfxt[0]=http://localhost:8088/docin-xfxt/syscache/clear
docin-sys.config.clearcacheurls.docin-xfxt[1]=http://localhost:8088/docin-xfxt/syscache/clear
docin-sys.config.clearcacheurls.docin-sys[0]=http://localhost:8088/docin-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-sys[1]=http://localhost:8088/docin-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-portal[0]=http://localhost:8088/docin-portal/syscache/clear
docin-sys.config.clearcacheurls.docin-stat[0]=http://localhost:8088/docin-portal/syscache/clear
docin-sys.config.clearcacheurls.hlw-xfxt[0]=http://localhost:8089/hlw-xfxt/syscache/clear
docin-sys.config.clearcacheurls.hlw-sys[0]=http://localhost:8089/hlw-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-xf-exchange[0]=http://localhost:8080/docin-xf-exchange/syscache/clear
具体清除缓存请求接口
@Api(value="公共基础请求-基础数据缓存处理",tags="公共基础请求")
@RestController
@RequestMapping(value="/syscache")
public class SysDataCacheController {
   
    
    @Autowired
    private CronClearSysDataCacheJob cronClearSysDataCacheJob;
    
    @ApiOperation(value="清理基础数据缓存", httpMethod="GET")
    @RequestMapping(value="/clear", method=RequestMethod.GET)
    public ApiResultDTO<RequestMsgTempVO> clearSyscache(HttpServletRequest request){
   
        return RestAPITemplate.restapi(()->{
   
            cronClearSysDataCacheJob.refreshCache();
            return null;
        });
    }
    
}
清除本地缓存
	@Autowired
    private ISysDataVersionService sysDataVersionService;
    //本地所获得基础数据最后更新时间戳
    private volatile long lastSysTimestamp = -1L;
    private volatile boolean refreshing=false;
    @Async("taskExecutor")//使用线程池 启动
    public void refreshCache() {
   
        logger.info("定时刷新令牌任务启动");
        if(this.refreshing) {
   
            logger.error("之前刷新任务还在堵塞中....");
            return;
        }
        try {
   
            this.refreshing = true;
            long lastSysTimestampOfServer = sysDataVersionService.getLastTimestampOfSysData();
            if(this.lastSysTimestamp!=lastSysTimestampOfServer) {
   
                this.lastSysTimestamp = lastSysTimestampOfServer;
                SysDataCacheAspect.clearCache();
                logger.warn("本地基础数据缓存已经清理,清理后本地基础数据版本为{}",lastSysTimestamp);
                Thread.sleep(5000);//防止攻击
            }else {
   
                logger.info("本地基础数据缓存的版本与基础数据服务一致,无需清理,本地基础数据版本为{}",lastSysTimestamp);
            }
        }catch (InterruptedException e) {
   
            e.printStackTrace();
        }finally {
   
            this.refreshing=false;
        }
    }
缓存逻辑
@Aspect   //定义一个切面
@Configuration
public class SysDataCacheAspect {
   
    private static Logger logger = LogManager.getLogger(SysDataCacheAspect.class);
    private static final  Map<String,Boolean> cacheFileNames = new ConcurrentHashMap<String, Boolean>();

    private static LoadingCache<String,Object> cache = null;
    static {
   
        // CacheLoader 初始化
        CacheLoader<String, Object> cacheLoader = new CacheLoader<String, Object>() {
   
            @Override
            // load方法的作用是在通过get方法从LoadingCache获取不到值时去加载该值并放入缓存。
            public Object load(String key) throws Exception {
   
                return null;
            }
        };
        cache = CacheBuilder.newBuilder()
                // 设置容量大小
                .maximumSize(80000)
                //默认一天后过期
                .expireAfterWrite(10, TimeUnit.DAYS)
                .removalListener(new RemovalListener<String, Object>() {
   
                    @Override
                    public void onRemoval(RemovalNotification<String, Object> notification) {
   
                        if(notification.getValue()!=null && notification.getValue() instanceof CacheFile) {
   
                            CacheFile cacheFile = (CacheFile)notification.getValue();
                            removeCacheFile(cacheFile.fileName);
                        }
                        
                    }
                })
                // 加载器配置
                .build(cacheLoader);
    }
    
    private String normalizedArgsStr(Object[] args){
   
        if(args==null || args.length==0) {
   
            return "";
        }
        Object[] normalizedArgs = new Object[args.length];
        if(args!=null) {
   
            for(int i=0;i<args.length;i++) {
   
                Object arg = args[i];
                
                if(arg instanceof AccessTokenUser) {
   
                    AccessTokenUser user = (AccessTokenUser)arg;
                    normalizedArgs[i]= user.getUserId();
                }else {
   
                    normalizedArgs[i]=arg;
                }
            }
        }
        return JsonConverter.toJsonStr(normalizedArgs);
    }
    
    @Around("execution(* (@com.xysd.bizbase.annotation.SysDataCache *).*(..)) || execution(@com.xysd.bizbase.annotation.SysDataCache * *(..))")
    public Object process(ProceedingJoinPoint point) throws Throwable {
   
        String className = point.getSignature().getDeclaringTypeName();
        String methodName = point.getSignature().getName();
        Object[] args = point.getArgs();
        String key = className+"_$_"+methodName+"_$_"+(normalizedArgsStr(args));
        Object cached = cache.getIfPresent(key);
        
        if(methodName.endsWith("_dontCache")){
   
            return point.proceed(args);
        }
        if(cached!=null) {
   
            if(cached instanceof CacheFile) {
   
                CacheFile cachedFile = (CacheFile)cached;
                Object cachedData =  readCachedData(cachedFile);
                if(cachedData==null) {
   
                    //读取缓存失败
                    return point.proceed(args);
                }else {
   
                    return cachedData;
                }
            }else {
   
                return cached;
            }
            
        }else {
   
            cached = point.proceed(args);
            if(cached instanceof ApiResultDTO){
   
                if(((ApiResultDTO<?>) cached).getData() == null) return cached;
            }
            if(cached!=null) {
   
                try {
   
                    CacheFile cachedFile = cacheToDiskIfNecessary(cached);
                    if(cachedFile!=null) {
   
                        cache.put(key, cachedFile);
                    }else {
   
                        cache.put(key, cached);
                    }
                    
                }catch(Exception e) {
   
                    logger.error("缓存失败,失败信息{}",e.getMessage());
                    e.printStackTrace();
                }
                
            }
            return cached;
        }
    }
    private Object readCachedData(CacheFile cachedFile) {
   
        String fileName = cachedFile.getFileName();
        String absolutePath = getAbsoluteCacheFilePath(fileName);
        File f = new File(absolutePath);
        InputStream in = null;
        ObjectInputStream oin = null;
        try {
   
            in = new FileInputStream(f);
            oin = new ObjectInputStream(in);
            Object cachedData = oin.readObject();
            return cachedData;
        }catch(Exception e) {
   
            logger.error("读取缓存序列化文件失败,失败信息:{}",e.getMessage());
            e.printStackTrace();
            return null;
        }
        finally {
   
            Utils.clean(in,oin);
        }
        
    }
    /**
     * 当value序列化后占用字节大于50K时写入磁盘进行缓存
     * @param value
     * @return
     */
    private CacheFile cacheToDiskIfNecessary(Object value) {
   
        int cachThreadshold = 50*1024;
        ByteArrayOutputStream bos = null ; 
        ObjectOutputStream oos = null;
        try {
   
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(value);
            oos.flush();
            byte[] byteArray = bos.toByteArray();
            if(byteArray!=null && byteArray.length>cachThreadshold) {
   
                return buildCacheFile(byteArray);
            }else {
   
                return null;
            }
        }catch(Exception e) {
   
            throw new RuntimeException(e);
        }finally {
   
            Utils.clean(bos,oos);
        }
    }
    
    private CacheFile buildCacheFile(byte[] byteArray) {
   
        String fileName = "syscachefile_"+Utils.getUUID("");
        String absolutePath = getAbsoluteCacheFilePath(fileName);
        File f = new File(absolutePath);
        OutputStream out = null;
        try {
   
            if(!f.getParentFile().exists()) {
   
                f.getParentFile().mkdirs();
            }
            out = new FileOutputStream(f);
            out.write(byteArray);
            out.flush();
            cacheFileNames.put(fileName, true);
            return new CacheFile(fileName);
        }catch(Exception e) {
   
            
            throw new RuntimeException(e);
        }finally {
   
            Utils.clean(out);
        }
        
    }
    
    private static String getAbsoluteCacheFilePath(String fileName) {
   
        String sysCacheBaseDir = Utils.getTmpDirRoot()+"/sysDataCache";
        return sysCacheBaseDir+"/"+fileName;
    }
    
    public static void removeCacheFile(String fileName) {
   
        if(StringUtils.isNoneBlank(fileName)) {
   
            cacheFileNames.remove(fileName);
            String absolutePath = getAbsoluteCacheFilePath(fileName);
            File f = new File(absolutePath);
            try {
   
                if(f.exists() && f.isFile()) {
   
                    f.delete();
                }
            }catch(Exception e) {
   
                //删除失败不做任何处理
                e.printStackTrace();
            }
        }
    }
    /**
     * 清空缓存
     */
    public static final void clearCache() {
   
        for(String fileName:cacheFileNames.keySet()) {
   
            removeCacheFile(fileName);
        }
        cacheFileNames.clear();
        cache.invalidateAll();
    }
    
    public static class CacheFile implements Serializable {
   
        private static final long serialVersionUID = -6926387004863371705L;
        private String fileName;
        public CacheFile(String fileName) {
   
            super();
            this.fileName = fileName;
        }
        public String getFileName() {
   
            return fileName;
        }
    }
}
拦截器

Hibernate的拦截器 监听实体变化

public class SysEntityUpdateListener extends EmptyInterceptor {
   

	/**
	 * 
	 */
	private static final long serialVersionUID = -7428554904158765594L;

	@Override
	public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
   
		super.onDelete(entity, id, state, propertyNames, types);
		SysDataChanged.changed();
	}

	@Override
	public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) {
   
		SysDataChanged.changed();
		return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
		
	}

	@Override
	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
   
		SysDataChanged.changed();
		return super.onSave(entity, id, state, propertyNames, types);
	}

	@Override
	public void postFlush(Iterator entities) {
   
		super.postFlush(entities);
	}

	@Override
	public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) {
   
		 
		return super.findDirty(entity, id, currentState, previousState, propertyNames, types);
	}

	@Override
	public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {
   
		SysDataChanged.changed();
		super.onCollectionRemove(collection, key);
	}

	@Override
	public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {
   
		SysDataChanged.changed();
		super.onCollectionUpdate(collection, key);
	}

}
记录是否要清理缓存
public class SysDataChanged {
   
	private static final ThreadLocal<Boolean> store = new ThreadLocal<Boolean>();
	/**
	 * 当前线程已经更改过基础数据
	 */
	public static final void changed() {
   
		store.set(true);
	}
	/**
	 * 重置
	 */
	public static final  void reset() {
   
		store.set(false);
	}
	/**
	 * 当前线程是否更改过基础数据
	 * @return
	 */
	public static final  boolean isChanged() {
   
		return Boolean.TRUE.equals(store.get());
	}

}

通过SysEntityUpdateListener监听实体变化,更改SysDataChanged.store.set(true)。当用户请求后端接口时,通过FireSysDataChangedEventFilter过滤器判断SysDataChanged.store.get()==true,从而触发restTemplate.getForObject(url, String.class)请求,更新各个项目本地的基础数据缓存SysDataCacheAspect.clearCache()。

相关推荐

  1. Filter过滤器学习使用

    2024-01-30 10:58:02       45 阅读
  2. 过滤器Filter

    2024-01-30 10:58:02       41 阅读
  3. 过滤器 -- Filter

    2024-01-30 10:58:02       35 阅读
  4. 【vue filters 过滤器】vue页面 全局使用

    2024-01-30 10:58:02       57 阅读
  5. SpringBoot Filter过滤器使用

    2024-01-30 10:58:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-30 10:58:02       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-30 10:58:02       97 阅读
  3. 在Django里面运行非项目文件

    2024-01-30 10:58:02       78 阅读
  4. Python语言-面向对象

    2024-01-30 10:58:02       88 阅读

热门阅读

  1. 什么是IDE?新手用哪个IDE比较好?

    2024-01-30 10:58:02       64 阅读
  2. Debezium日常分享系列之:Debezium 2.6.0.Alpha1发布

    2024-01-30 10:58:02       58 阅读
  3. Python 和 LLM 的完美融合之路 (再谈 Function Impl)

    2024-01-30 10:58:02       46 阅读
  4. ECMAScript日常总结--ES2019(ES10)

    2024-01-30 10:58:02       42 阅读
  5. 测试面试题常见题

    2024-01-30 10:58:02       48 阅读
  6. dfs专题 P1706 全排列问题——洛谷(题解)

    2024-01-30 10:58:02       59 阅读