1、Mybatis 一级缓存(sqlSession)、二级缓存(需要开启)mapper级别的(namespace)
- MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
- MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
- 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis,Memcached等分布式缓存可能成本更低,安全性也更高。
2、对象复制
1、通过set方法
2、通过Object的clone方法 默认是浅复制 如果深复制的话重新object clone()方法
3、工具类BeanUtils和PropertyUtils进行对象复制
Student stu1 = new Student();
stu1.setNumber(12345);
Student stu2 = new Student();
BeanUtils.copyProperties(stu2,stu1);
这种写法无论多少种属性都只需要一行代码搞定,很方便吧!除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而PropertyUtils不支持这个功能,但是速度会更快一些。在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。
4、通过序列化实现对象的复制
序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作
3、springboot内置那些容器
jetty tomcat undertwo
4、Springboot启动流程
Spring Boot程序有一个入口,就是main方法。main里面调用SpringApplication.run()启动整个Spring Boot程序,该方法所在类需要使用@SpringBootApplication注解。
@SpringBootApplication包括三个注解:
@EnableAutoConfiguration:SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置。简单概括一下就是,是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。
@Configuration:它就是JavaConfig形式的Spring Ioc容器的配置类。被标注的类等于在spring的XML配置文件中(applicationContext.xml),装配所有bean事务,提供了一个spring的上下文环境。
@ComponentScan:组件扫描,可自动发现和装配Bean,功能其实就是自动扫描并加载符合条件的组件或者bean定义,最终将这些bean定义加载到IoC容器中。可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。默认扫描SpringApplication的run方法里的Booter.class所在的包路径下文件,所以最好将该启动类放到根包路径下。
4、jvm内存模型
5、springboot启动后执行某个方法的三种实现方式,且不影响提供服务
第一种方式,应该也是最简单的方式
直接在方式上面注入,但是会影响服务提供,比如这个方法要执行五分钟 这五分钟之内是无法提供服务的,这个方法是在服务初始化后之前运行, 所以 此方法运行不结束,服务就无法初始化, 在这过程路也无法提供服务
@PostConstruct
public void pingStart(){
System.out.println(" ping start:");
getPingip();
System.out.println(" ping end: ");
}
第二方式,是通过监听接口方式启动,服务已经初始化过,不影响 服务启动,并且启动之后可以正常提供服务
@Component
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
private QuartzManager quartzManager;
/**
* 初始启动quartz
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
quartzManager.start();
System.out.println("任务已经启动...");
} catch (Exception e) {
e.printStackTrace();
}
}
第三种也是监听接口方式,启动服务,执行方式时仍然提供服务,服务初始化之后,执行方法
@Component
public class StartPingService implements CommandLineRunner{
@Autowired
Ping ping;
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
ping.pingStart();
}
}