记录一下看公司项目学到的新东西

一些没见过但是能看懂的新鲜玩意儿

1.@within注解


这个注解是Spring AOP里面的一个注解,和@target作用类似,都是用于配置切点(基于注解的形式)的,区别在于:

//表示的是对标注了A1注解的类里面所有的方法,包括子类里面没有重写父类的方法都可以被看做是切点
@Around("@within(com.example.A1)")
//表示的是对标注了A1注解的类里面所有的方法,都可以看做切点
@Around("@target(com.example.A1)")

因为平常写AOP的时候没有写过对类的全部方法进行增强的情况,所以第一次看到@within注解有点陌生


2.Methods annotated with '@Transactional' must be overridable


这句话翻译过来的意思就是被@Transactional修饰的方法必须是可重写的,我在公司的代码里发现前辈在静态方法上面使用了@Transactional注解,典型错误啊,也同时对应了两个知识点

静态方法不能重写

@Transactional不能用在不可重写的方法上,比如final,static方法上

其次可以回顾一下为什么@Transactional不能用在不可重写的方法上,我思考了一下是因为动态代理,因为事务的底层是AOP,AOP底层是动态代理,动态代理里面有常见的两种,JDK动态代理和CGLIB动态代理,一种是通过基于接口实现,一种是创建子类实现,都需要重写父类的方法,如果修饰不可重写的方法自然就矛盾了


3.@Async注解


这个注解我见过,但是一直没用过,看了前辈的用法大概了解了使用的过程

@Async(),异步注解,被这个注解修饰的方法将不会阻塞主方法的运行,里面可以传一个value参数,代表着你需要用哪个线程池,如果不传则会使用系统默认的线程池

他所使用的线程池我也没见过,用的是ThreadPoolTaskExecutor,我一开始还没发现这个东西我没见过,直到我看到了他在里面调用了executor.initialize();,我记得我当时学JUC的时候没有用过这个方法,好像是直接创建完线程池就直接用了,后来才发现这个ThreadPoolTaskExecutor根本不是util.concurrent包下的,而是spring里面的线程池,是对ThreadPoolExecutor的一个封装

然后他们是把线程池当做一个Bean创建出来了,在里面配置了核心线程数,最大线程数,队列大小,名称前缀和拒绝策略,这些值都是通过@Value注解从配置文件里面读取的

另外在使用这个注解之前得先开启异步支持,得在启动类或者配置类上加上@EnableAsync注解


4.@Valid注解


这个注解也是见过但没有用过的,在controller层的方法入参前面加上@Valid注解,在方法执行前就会去找到对应实体类,看看哪些属性上有限制。

但是他们每个入参上都加上了这个注解,但是每个实体类里都没有加限制条件,可能是有备无患吧


5.BindingResult


确确实实没见过这个类,也是spring提供的一个类,可以自动接收@Valid校验结果之后的值,用法如下

public Result getResponse(@Valid @RequestBody LoginRequest request,BindingResult result){
   //先去判断result结果,看看是校验通过还是没通过,可以写个工具类来判断
   ParameterValidator.validate("getSystemResp",validResult);
}
//工具类,判断是否有错,有错的话就记录参数和错误信息并抛异常
   public static void validate(String serviceName, BindingResult result) throws ServiceException {
       if (result.hasErrors()) {
           StringBuffer buffer = new StringBuffer();
           buffer.append(serviceName + "接口参数校验不通过:");
           for (FieldError error : result.getFieldErrors()) {
               buffer.append(error.getField() + error.getDefaultMessage() + ", ");
          }
           String msg = buffer.toString();
           throw new ServiceException(msg.substring(0, msg.lastIndexOf(",")));
      }
  }


6.LogFactory.getLog


这个是apache包里面的日志记录方法,我一开始不明白为什么这个方法里要传入class对象,后来一查发现class对象是用来做日志标题起到区分作用的,我平常打日志全都是log.infolog.error这样,我只知道他会在控制台有输出,至于他会保存吗,他保存到哪里,线上出问题了我该怎么看日志,这些我都不明白,还是得去看看相关资料


7.ESB


#esb调用
esb.op.id = ********
esb.password = ********************

在配置文件里看到了这样一段配置,就去查了一下ESB是什么意思

ESB是Enterprise Service Bus的简称,中文翻译为企业服务总线,企业服务总线是一个实现系统间集成和互联互通的重要技术架构,可以理解为是一种消息和服务集成的中间件平台。

简单来说就是用来降低系统互联的复杂度,假如一个业务系统有十几个小系统,他们如果彼此互相链接就会错综复杂,如果这些系统又是由不同的厂家制作,那么系统构建语言不同,数据传输格式不同,通信协议不同,这样统一起来就很麻烦,于是ESB相当于一个中台,统一的接收所有请求,进行消息转换后再转发给接收请求的系统

具体的内容可以看这篇文章:https://www.jianshu.com/p/10ec5b86296f


8.spring.jms


#指定最小的并发消费者数量
spring.jms.listener.concurrency=5
#指定最大的并发消费者数量
spring.jms.listener.max-concurrency=10

又是一段没有看过的配置,去查了一下知道,这个jms是Java Messaging Service的缩写,是Java平台面向消息中间件推出的统一API(和JDBC类似,JDBC也支持各个数据库)

虽然但是,知道了jms是啥但也不知道怎么用,项目里除了配置里有写,其他地方好像没有用到mq啊


9.spring.sleuth


#开启sleuth支持
spring.sleuth.enabled=true
#跟踪信息收集采样比例,默认 0.1,为 1 是即 100%,收集所有
spring.sleuth.sampler.percentage=1.0

又是spring的东西,项目组的前辈应该对spring的各个组件都很了解了吧

Sleuth 通过 traceId 实现了对分布式系统调用链路的跟踪。在一次服务请求链路中,会保持并传递一个 traceId,从而将不同服务的请求跟踪信息串联起来,不同服务的 traceId 相同表示处在同一请求链中。

是个实现链路追踪的组件,我还没有接触过,现在主流的链路追踪工具是skywalking和prometheus,sleuth就没怎么听说过了


0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP