单例模式引起的一些思考

单例模式通常有饿汉式和懒汉式,懒汉式

饿汉式

无线程安全性问题

1
2
3
4
5
6
7
8
9
public class SingleHungryStyle {
private static SingleHungryStyle instince = new SingleHungryStyle();

public static SingleHungryStyle getInstince(){
return instince;
}

}

懒汉式

阅读更多

JDK1.7和1.8中的HashMap区别

Jdk1.7和1.8中,HashMap的一些关键点几乎重写了。

主要变更点:

1. hash扰动算法

在jdk1.7的时候,HahMap的hash扰动算法如下:

1
2
3
4
5
6
7
8
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

阅读更多

Java集合学习之HashSet

简介

在一般的使用中,HashSet经常用于数据的去重,例如我们有一个List,这个List里面有一些重复的数据,于是我们便可以这样操作

1
2
3
4
5
6
7
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
Set<String> set =new HashSet<>();
set.addAll(list);

此时,在Set里面,只会有一个a元素。

底层

阅读更多

Spring中AOP的探索与实践(二)之Mongo多数据源切换

在之前的一片文章中介绍了使用AOP的方式来实现Redis的多数据源切换。而今天这一篇则是主要讲述Mongo的多数据源切换。

使用AOP来实现Mongo的数据源切换与Redis的AOP切换相同,不同之处是需要替换MongoRepository里面的MongoOperations,从而实现多数据源的切换

代码示例

配置类,读取Mongo的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Configuration
public class MongoMultiProperties {

private static final Logger LOGGER = LoggerFactory.getLogger(MongoMultiProperties.class);

@Bean(name="mongodb1")
@Primary
@ConfigurationProperties(prefix = "spring.data.mongodb.db1")
public MongoProperties db1Properties(){
LOGGER.info("正在初始化db1");
return new MongoProperties();
}

@Bean(name = "mongodb2")
@ConfigurationProperties(prefix = "spring.data.mongodb.db2")
public MongoProperties db2Properties(){
LOGGER.info("正在初始化db2");
return new MongoProperties();
}

}
阅读更多

Spring中AOP的探索与实践(一)之Redis多数据源切换

一般在项目的使用过程中,有时候为了减轻数据库的压力,从而将一部分数据缓存至Redis,但是随着业务量的增多。我们所需要的Redis服务器也会越来越多,就算不需要多个Redis数据源,那么在一个redis里面,切换不同的DB也是很麻烦的一件事情。

非AOP的一般的多数据源操作

在Redis的多数据源使用中,一般的方法是从配置文件中读取多个RedisProperties,读取到配置文件之后,将RedisProperties配置到RedisTemplate,然后每次使用的时候就通过不同的Template来调用Redis服务器。示例如下:

代码示例

Redis的配置类

阅读更多

使用Mq实现延时队列

在实际的应用开发中,下游系统并不需要立即处理上游系统的mq,但是又不可能将消息阻塞在上有系统中。且这两个系统之间又没有接口提供出来。这个时候就需要通过Mq的死信队列来实现一个延时效果

简介

由于Mq的发送方不支持延迟发送(目前的新版本可以使用插件来支持,但是可能由于公司的其他限制,导致无法升级),这时候就需要使用Mq的死信队列来实现延时队列

一般情况下,Mq的发送流程如下:

阅读更多

在Mysql中使用变量进行复杂的查询(一)

注意,此文章使用的Mysql变量均是用户变量

简介

首先看一个需求,有如下数据表:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1 order by area_id;
+---------+-----------+
| area_id | order_num |
+---------+-----------+
| 1 | 22 |
| 1 | 10 |
| 1 | 10 |
| 2 | 10 |
| 2 | 10 |
| 2 | 22 |
| 3 | 10 |
+---------+-----------+
7 rows in set (0.14 sec)

可以看到,这是一个很非常普通的数据表。

阅读更多

java异步IO的回调机制

异步

在Java的nio里面,经常遇到的一个词语是回调,一个主线程负责分发各种请求至子线程,同时子线程处理完毕之后通知主线程,这其中就涉及到了回调机制。

在Java中,异步IO的回调方式主要是CallBackFuture

由于Future获取结果是一种阻塞的方式,所以本次就主要来了解Callback回调方式的运行机制。

由于在异步IO里面,主线程不需要等待子线程来获取结果,所以可以极大的提高程序运行的效率,但是子线程必须在完成之后通知父线程,于时这就引出了回调。

阅读更多

SSO单点登录的理论与实践(一)

SSO简介

随着企业业务的发展,企业中可能会出现多个业务的系统。如果是对内使用的话,那稍微还好点,如果是ToC的业务,客户如果每进入一个系统都需要登录的话,对用户来说是一个麻烦事情,很可能会造成用户的流失。

如果在每一个系统里面都存储一份用户的账号和密码数据,这种做法显然是不靠谱的,而且也不安全的。会造成客户的数据大量冗余,而且还会导致后期维护十分的麻烦。

所以,现在一般都会采用SSO单点登录

在介绍SSO登录之前,需要先了解一下浏览器的同源策略

阅读更多

在Spring中全局处理异常

随着业务的发展,在每一个业务模块里面都可能会出现一些自定义的通用异常,例如·验证失败权限不足等等 ,这些自定义的异常很可能会被所有模块公用,在代码里面,最常见的一种写法是在每一个方法里面进行捕获,然后在Controller里面进行catch,最后进行相应处理

常见写法

第一种写法:

这是一个常规的写法,每一个方法都处理自己的特定异常
Controller层

1
2
3
4
5
6
7
8
9
10
11
public void login(){
try{
//逻辑处理
}catch(AuthException e){
XXX
}catch(CrsfException e){
XXX
}catch(Exception e){
XXX
}
}
阅读更多