不知道标题叫啥的学习笔记

1.maven基于java ,所以配置环境变量应先配置java再配置maven

2.关于压缩包后缀

tar.gz属于linux环境

zip属于windows环境

3.事务手动回滚

 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

配合 @Transactional 注解一起使用

之前我好奇我同事为什么要在拦截里手动回滚,不是已经有@Transactional 注解了么

后来才知道,有try catch的情况下,事务会失效

4.synchronized锁this和锁class的区别

synchronized(this) 只锁定当前new出来的对象 比方A a1 = new A();   A a2 = new A(); 他只锁住a1或者只锁住a2

synchronized(A.class) 锁全局 不管new出来的哪个对象都被锁住  下图是一个使用例子  注意final Class

5.private方法写了注解也无法增强

两种说法 1.springAOP不会去管理private方法  2.spring AOP无法实现或者继承private方法

反正结果是:private方法不会走AOP,不生效

6..druid和普通配置

在引入德鲁伊之后,我发现以下两种配置的效果是相同的

spring.datasource.druid.url=jdbc:h2:tcp://172.11.11.111:11111/openapi;AUTO_SERVER=TRUE;
spring.datasource.druid.driver-class-name=org.h2.Driver
spring.datasource.druid.username=openapi
spring.datasource.druid.password=openapi@123
spring.datasource.url=jdbc:h2:tcp://172.11.11.111:11111/openapi;AUTO_SERVER=TRUE;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=openapi
spring.datasource.password=openapi@123

然后翻了翻源码,找到了名字带AutoConfig的配置文件,发现他这两个配置都读  那个@EnableConfigurationProperties

7.@DependsOn 设置bean的加载顺序

不是简单的order 而是设置条件 当一个bean加载之后,再加载当前bean

在加载dynamicDataSourceFactory 这个bean之后 再加载当前 DynamicRoutingDataSource 这个bean

踩坑记录:部署到线上之后,由于当前bean引用了另一个bean   一直报空指针,猜想可能与bean的加载顺序有关,所以使用@DependsOn,问题解决

补充:今天看到@AutoConfigureAfter这个注解也有相似的地方,先加载指定配置类再加载当前配置类,是需要有@Configuration注解的,网上说还需要spring.factories配置的

8.线上启动报错,找不到SubscriberDataObserver类

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'channelInfoService': 
Invocation of init method failed; 
nested exception is com.alipay.sofa.runtime.api.ServiceRuntimeException: 
Unable to get implementation of reference component, 
there's some error occurred when register this reference component.

注意caused by 

Caused by: java.lang.ClassNotFoundException: com.alipay.sofa.registry.client.api.SubscriberDataObserver

解决办法: SubscriberDataObserver是registry-client-all包下的,pom中引入依赖

        <!--SOFARegistry客户端-->
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>registry-client-all</artifactId>
            <version>5.2.1</version>
        </dependency>

9.启动报错日志中,看到依赖包后边有叹号

第一眼就觉得是版本冲突问题,确实,引入sofa-boot时没有指定版本号,就是用默认版本了

解决办法:指定版本号

    <!--sofa boot rpc-->
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>rpc-sofa-boot-starter</artifactId>
            <version>5.5.2</version>
        </dependency>

10.当引入依赖不指定版本号

两种情况,一种会报错一种不会报错

当你的<parent>中已经引入了该依赖,不指定版本号时不会报错,会默认引入父依赖中指定的版本,

但是如果你指定了版本号,那就引入你指定的版本号,覆盖了父依赖的

比如我引入了sofaboot-dependencies,然后sofaboot-dependencies中本来就引入了rpc-sofa-boot-starter

    <parent>
        <groupId>com.alipay.sofa</groupId>
        <artifactId>sofaboot-dependencies</artifactId>
        <version>3.1.5</version>
    </parent>

我再我得项目中又去引入rpc-sofa-boot-starter,不写版本号,就不会报错,但是会引入默认版本

sofaboot-dependencies是3.1.5时,rpc-sofa-boot-starter的默认版本是6.0.3

但我像上边的6一样指定了版本号,那么此时引入的rpc-sofa-boot-starter版本就是5.5.2

11.对象转json

起因:对象转json会走这个实体的一个get方法,但是这个get方法在这个实体中并没有对应的属性,比如getDoubleValue(),并没有doubleValue属性

看了转json的原理:原来只要有get方法就可以

https://blog.csdn.net/Topdandan/article/details/80369870

public String getIdName() {
		return id+name;
	}

String json=JSON.toJSONString(s);
System.out.println(json);

上面的输出结果为:

{"id":23,"idName":"23呵呵","name":"呵呵"}

可以看到,student对象中并无idName属性,但却有相应的键值对,所以只需要一个getXxx()方法!

可以看到,对象中并无doubleValue属性,但却有相应的键值对,所以只需要一个getDoubleValue()方法!

11.1.不想在转json时候走这个get方法怎么办

@JSONField(serialize = false)

 本来用@ JsonIgnore,但是对于fastjson不生效

12.排除jar包

情景:某个项目A要脱离一个项目B运行,但是这个项目A中已经引入了一些B代码,需要把这部分代码复制出来,

并且A的pom中没有直接引入B,而是A间接引入了项目C,然后项目C中引入了项目B

解决办法,既然是C引入了B,就直接引入C,然后在C中排除B

排除之后,关于B的代码就会报错,可以直接摘出来

  <dependency>
     <groupId>com.wish.plat</groupId>
     <artifactId>p-bc-commons</artifactId>
     <version>0.1.1-SNAPSHOT</version>
     <exclusions>
           <exclusion>
                <groupId>com.wish.plat</groupId>
                <artifactId>plat-parameter-api</artifactId>
           </exclusion>
     </exclusions>
  </dependency>

13.连接池的作用

以前一直不知道,到底为什么要弄一个池子管理链接

重点是:实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,
1.为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection
这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池

2.用池来管理Connection,这样可以重复使用Connection。

有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象

当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。

池就可以再利用这个Connection对象了。

14.线程池的作用

线程池作用就是限制系统中执行线程的数量
使用线程池有如下作用:

  1. 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
  2. 可以根据系统的承受能力,调整线程池中工作线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

15.@Qualifier注解的用处

当一个接口有多个实现的时候,为了指名具体调用哪个类的实现

16.不加访问修饰,默认friendly

补习以下基础

如果一个类的成员没有任何权限修饰,那么它门就是缺省包访问权限,用friendly来表示,注
friendly不是Java中的关键字,这里是个人喜欢的方式用它表示而已。同一个包内其它类可以访问,但包外
就不可以

18.优雅的拼接字符串

可以用StringBuffer,StringBuilder。如果只拼接一个,也可以用String提供的函数

String由concat方法,不用加号+了

concat(String str)
   说明:将指定字符串连接到此字符串的结尾。
   返回:String

示例:
        String str = "abc";
        str = str.concat("123");
        System.out.println(str);
输出结果:abc123

19.优雅的toString()

MoreObjects.toStringHelper

通过.add方法拼接节点

20.以小数点分割

在Java中小数点是一个特殊符号,是对象调用属性和方法的特殊符号,所以编译会出错的,用\\是把小数点转义成单纯的小数点

String[] split = attr.split("\\.");

关于java中转义字符的使用 https://www.cnblogs.com/cai170221/p/7098802.html

21.bigdecimal

21.1double转bigdecimal  先转string再转bigdecimal

先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法

 BigDecimal bd1 = new BigDecimal(Double.toString(a));

21.2除法时抛出异常

BigDecimal rate = new BigDecimal(1).divide(new BigDecimal(3), 6, BigDecimal.ROUND_HALF_UP);
1除以3  保留六位小数  向上取整

21.3.double计算保留两位小数

运算后结果可以用.doubleValue再转成double

 public static double divide(double a, double b, int scale){
         BigDecimal bd1 = new BigDecimal(Double.toString(a));
         BigDecimal bd2 = new BigDecimal(Double.toString(b));		 
		 //运算完再转成double
         return bd1.divide(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
     }

21.4.bigdecimal的加减乘除

不是符号   有自己的方法   比如上边的除

22.@RestController与@Controller

@RestController相当于@ResponseBody+@Controller

比如   在类上边加@Controller 再在类中一个方法上加@ResponseBody  返回的就是json

没有@ResponseBody注解的方法  返回的就是一个页面

@Controller
public class HelloController {
    
    @GetMapping(value="/hello")
    @ResponseBody
    public String say(){//返回json 数据  
        return "gril";
    }
    @GetMapping(value="/hello1")
    public String say1(){//返回视图
        return "sys/index1";
    }
}

如果用@Controller返回页面   根据yml中配置的前缀后缀去找具体页面名称 

24.异常转换之后找不到哪行代码报错

这个困扰我时间还挺长的,开始感觉无从下手

后来组长提示:把错误日志打出来就行了

但是,业务逻辑那么多,都打印出来能累死

解决办法:在拦截中可以e.printStackTrace

有两种解决办法

24.1.在网上找的

ByteArrayOutputStream exception= new ByteArrayOutputStream();		
1.将异常栈信息先输出到ByteOutputStream 
2.然后再将ByteOutputStream 转换为字符串
3.就获得了异常的完整输出
e.printStackTrace(new PrintStream(exception));
String excepString = exception.toString();	
log.err(excepString )

24.2.apache提供的工具类

ExceptionUtils.getStackTrace(Throwable throwable)

org.apache.commons.lang3.exception下
因为Throwable是异常父类(老大),所以任何异常都可以用这个方法
  public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        throwable.printStackTrace(pw);
        return sw.getBuffer().toString();
    }

两种方法的原理都是把e.printStackTrace输出到一个地方,然后放到log中

24.3.我的部分代码

ExceptionUtils.getStackTrace

 } catch (RuntimeException runtimeException) {
            String stackTrace = ExceptionUtils.logStackTrace(runtimeException);
            log.error(stackTrace);
            pf1013.setReturnMessage(runtimeException.getMessage());//返回信息
            pf1013.setErrorInfo( "exception"+ExceptionUtils.getStackTrace(runtimeException).substring(0,7000));
            throw new BizRuntimeException(ERR_CODE_BUSS_CHECK_PF_000075,runtimeException.getMessage());
        } catch (FormatException formatException) {
            String stackTrace = ExceptionUtils.getStackTrace(formatException);
            log.error(stackTrace);
            pf1013.setErrorInfo( "exception"+stackTrace.substring(0,7000));
            throw new BizRuntimeException(ERR_CODE_BUSS_CHECK_PF_000075, formatException.getMessage());
        } catch (Exception exception) {
            String stackTrace = ExceptionUtils.getStackTrace(exception);
            log.error(stackTrace);
            pf1013.setErrorInfo("exception"+ExceptionUtils.getStackTrace(exception).substring(0,7000));
            throw exception;
        } catch (Throwable throwable) {
            String stackTrace = ExceptionUtils.getStackTrace(throwable);
            log.error(stackTrace);
            pf1013.setErrorInfo("exception"+ExceptionUtils.getStackTrace(throwable).substring(0,7000));
            throw throwable;

25.一个坑人的bug

同事找我帮他看他为什么强转失败,症结居然是:他引入的项目中有一个实体类,自己的项目居然新建了同一个名字的实体类,然后用两个不同的实体类强转! 

28.创建对象的几种方式

1.new

2.反射

3.clone

4.反序列化

29.jdbc完整的访问数据库的过程

1.导包  java.sql

2.加载驱动 class.forname

3.连接数据库 用户名密码url

4.执行查询 statement

5.解析返回值 自己创建实体解析

6.手动关闭连接 .close

mybatis底层用的也是jdbc,如preparestatement

31.相互引用解决办法

遇到一个问题,两个项目都要引用对方的东西,但是循环相互引用肯定是不可能的了。

解决办法

把两个项目都想要用的东西写在被引用哪个项目里,比如下图  plat-approval-api是接口层,需要用到实体作为返回类型,但是之前实体我是写道plat-approval-engine里边的,但是plat-approval-engine是实现impl层,肯定要引用 plat-approval-api,但是不能循环引用,所以把实体写到plat-approval-api里边,这样plat-approval-api本身可以直接用实体,然后plat-approval-engine中pom依赖中还是有plat-approval-api,也可以引用。完美解决

32.sofarpc初次接触

这个新公司和阿里云有合作,所以比较喜欢用阿里的东西

sofarpc是通过调用类名和方法提供服务的,并不是调用接口的方式

33.项目之间的引用构建关系

p被ext引用,ext被m引用。那么,p重新构建之后,m想用p中新的代码,是否需要重新构建ext?

答:不用

34.接着上边,如果p和m用@ImportResource了同一个资源

@ImportResource注解用于导入Spring的配置文件,让配置文件里面的内容生效

重复加载,报错

35.明明有这个类,但是报找不到

原因:启动类的扫描路径中不包括这个

解决办法:在启动类的扫描路径中加上报错路径,如下

36.不在循环中查数据库的解决办法

 在循环之前,把结果集查到,循环中,从这个结果集里边取

改之前的代码

改之后的代码

 

37.打包配置

1.默认打包为jar包 可以不写

2.名称

项目名+版本号.jar

artifactId-version.package     这几个标签拼接起来的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值