为什么Spring官方推荐通过构造器注入
一
我们在使用Spring的时候,最方便的就是它的IOC(控制反转),也就是所有的Bean都交由
Spring进行管理,那么我们在看网上的文章或者自己在写代码的时候经常会像这样写:
1 |
|
但是貌似许多人都会使用第一种方式,因为这样简单方便,如果是采用第二种的话,每一次新增加一个bean,都需要在构造器的入参上面加一个参数,就会显得有点麻烦。
我们在使用Spring的时候,最方便的就是它的IOC(控制反转),也就是所有的Bean都交由
Spring进行管理,那么我们在看网上的文章或者自己在写代码的时候经常会像这样写:
1 |
|
但是貌似许多人都会使用第一种方式,因为这样简单方便,如果是采用第二种的话,每一次新增加一个bean,都需要在构造器的入参上面加一个参数,就会显得有点麻烦。
在JDK1.8里面,ConcurrentHashMap
在put方法里面已经将分段锁移除了,转而是CAS锁和synchronized
ConcurrentHashMap
是Java里面同时兼顾性能和线程安全的一个键值对集合,同属于键值对的集合还有HashTable
以及HashMap
,HashTable
是一个线程安全的类,因为它的所有public
方法都被synchronized
修饰,这样就导致了一个问题,就是效率太低。
虽然HashMap
在JDK1.8
的并发场景下触发扩容时不会出现成环了,但是会出现数据丢失的情况。
所以如果需要在多线程的情况下(多读少写))使用Map集合的话,ConcurrentHashMap
是一个不错的选择。
ConcurrentHashMap
在JDK1.8的时候将put()方法中的分段锁Segment
移除,转而采用一种CAS
锁和synchronized
来实现插入方法的线程安全。
如下代码:
1 | /** Implementation for put and putIfAbsent */ |
Jdk1.7和1.8中,HashMap的一些关键点几乎重写了。
在jdk1.7的时候,HahMap的hash扰动算法如下:
1 | static int hash(int h) { |
在一般的使用中,HashSet经常用于数据的去重,例如我们有一个List,这个List里面有一些重复的数据,于是我们便可以这样操作
1 | List<String> list = new ArrayList<>(); |
此时,在Set里面,只会有一个a
元素。
在之前的一片文章中介绍了使用AOP的方式来实现Redis的多数据源切换。而今天这一篇则是主要讲述Mongo
的多数据源切换。
使用AOP来实现Mongo的数据源切换与Redis的AOP切换相同,不同之处是需要替换MongoRepository
里面的MongoOperations
,从而实现多数据源的切换
配置类,读取Mongo的配置
1 |
|
一般在项目的使用过程中,有时候为了减轻数据库的压力,从而将一部分数据缓存至Redis,但是随着业务量的增多。我们所需要的Redis服务器也会越来越多,就算不需要多个Redis数据源,那么在一个redis里面,切换不同的DB也是很麻烦的一件事情。
在Redis的多数据源使用中,一般的方法是从配置文件中读取多个RedisProperties
,读取到配置文件之后,将RedisProperties
配置到RedisTemplate
,然后每次使用的时候就通过不同的Template
来调用Redis服务器。示例如下:
在Java的nio里面,经常遇到的一个词语是回调
,一个主线程负责分发各种请求至子线程,同时子线程处理完毕之后通知主线程,这其中就涉及到了回调机制。
在Java中,异步IO的回调方式主要是CallBack
和Future
。
由于Future
获取结果是一种阻塞的方式,所以本次就主要来了解Callback
回调方式的运行机制。
由于在异步IO里面,主线程不需要等待子线程来获取结果,所以可以极大的提高程序运行的效率,但是子线程必须在完成之后通知父线程,于时这就引出了回调。
随着企业业务的发展,企业中可能会出现多个业务的系统。如果是对内使用的话,那稍微还好点,如果是ToC的业务,客户如果每进入一个系统都需要登录的话,对用户来说是一个麻烦事情,很可能会造成用户的流失。
如果在每一个系统里面都存储一份用户的账号和密码数据,这种做法显然是不靠谱的,而且也不安全的。会造成客户的数据大量冗余,而且还会导致后期维护十分的麻烦。
所以,现在一般都会采用SSO单点登录
在介绍SSO登录
之前,需要先了解一下浏览器的同源策略
随着业务的发展,在每一个业务模块里面都可能会出现一些自定义的通用异常,例如·验证失败
,权限不足
等等 ,这些自定义的异常很可能会被所有模块公用,在代码里面,最常见的一种写法是在每一个方法里面进行捕获,然后在Controller
里面进行catch,最后进行相应处理
第一种写法:
这是一个常规的写法,每一个方法都处理自己的特定异常
Controller层
1 | public void login(){ |
随着业务的发展,很可能需要在一个项目里面同时使用多个数据源。
大致看了网上的多数据源Demo,发现无非有两种:
一种是自己封装多个
JdbcTemplate
,然后调用对应的数据库就使用对应的JdbcTemplate
一种是通过注解的方式来实现,在需要切换数据源的方法上添加一个自己封装的注解便可以完成切换。
考虑了一下以后的扩展性和通用性,便决定采用基于注解的多数据源方式