#sword
Java高级编程中的利器(英文Sword,指的是" 宝剑", 像宝剑一样的利器)
里面包含了一致性hash,cassandra数据库的使用,ApplicationContextAware等
序号 | 项目名称 | 简介 |
---|---|---|
1 | consistent-hash | 一致性哈希的入门示例, 可以实现分布式存储 |
2 | cassandra-demo | cassandra列存储数据库的入门 |
3 | sword-springboot | AppContextHolder(可获取到ApplicationContext) |
详细介绍
Java implementation of consistent-hashing
cassandra数据库的入门编程
基于java的一致性hash的实现
一致性hash(consistent-hashing), 致性哈希算法在1997年由麻省理工学院提出(参见扩展阅读[1]),设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用。
主要用于分布式缓存的实现
比如弹性伸缩(动态扩容) redis存储节点的增加和减少的时候,可以把需要迁移和hash()值的变化量做到最小。
com.appjishu.swordboot.boot.AppContextHolder
应用场景:
一般情况下,使用SpringMVC/SpringBoot的时候,各种bean注册到Spring容器里了,然后在需要这个bean的地方,
使用@Autowired
或者@Resource
标注的bean都可以被自动注入。 但是在某些场景下,
需要手动注入。比如在一个Util里面,这个Util里面的方法都是static的,这个时候,如果需要获取Spring容器中的某个
bean,或者获取到ApplicationContext, 这个时候,就需要一个ApplicationContext Holder的东西,这里命名为AppContextHolder
其实Spring里有一个接口就是为了这个应用场景而生的ApplicationContextAware
本人就开发了一个com.appjishu.swordboot.boot.AppContextHolder
实现了这个接口, 源码如下:
package com.appjishu.swordboot.boot;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
*
* @author liushaoming
*
*/
@Component
public class AppContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (AppContextHolder.applicationContext == null) {
AppContextHolder.applicationContext = applicationContext;
}
}
// 获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
// 通过name获取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
// 通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
// 通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
使用的时候,很简单, 就像使用Spring原生的ApplicationContext一样, 现在要获取一个已经注册到容器里的一个bean Student
@Configuration
public class SysConfig {
@Bean(name = "myStudent")
public Student student() {
Student student=new Student();
student.setName("Frank Liu");
student.setAddress("Shanghai");
return student;
}
}
使用AppContextHolder获取bean的操作
Student student0 = (Student) AppContextHolder.getBean("myStudent");
// 或者
Student student1 = (Student) AppContextHolder.getBean(Student.class);
log.info("student0.name={}", student0.getName());
测试方法:
在idea/eclipse里,导入maven项目sword-springboot, 右键运行SwordBootApp -> run as -> Java Application
这是一个springboot项目,打开浏览器访问地址http://localhost:15000/test
可以运行测试AppContextHolder的测试代码, 贴出TestUtil里的方法
public class TestUtil {
private static final Logger log = LoggerFactory.getLogger(TestUtil.class);
public static void testAppContextHolder() {
log.info("--testAppContextHolder start---");
Student student0 = (Student) AppContextHolder.getBean("myStudent");
Student student1 = (Student) AppContextHolder.getBean(Student.class);
// 如果"student0 == student1"成立,则验证了AppContextHolder的确能获取到Spring容器ApplicationContext
// 而且Spring容器默认注册bean使用的是单例模式
log.info("student0==student1? {}", student0 == student1);
log.info("-------------------");
log.info("student0.name={}", student0.getName());
log.info("student0.address={}", student0.getAddress());
log.info("-------------------");
log.info("student1.name={}", student1.getName());
log.info("student1.address={}", student1.getAddress());
log.info("--testAppContextHolder done---");
}
}
打印结果: 说明测试成功了
2019-01-06 15:43:47.563 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : --testAppContextHolder start---
2019-01-06 15:43:47.564 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : student0==student1? true
2019-01-06 15:43:47.564 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : -------------------
2019-01-06 15:43:47.565 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : student0.name=Frank Liu
2019-01-06 15:43:47.565 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : student0.address=Shanghai
2019-01-06 15:43:47.566 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : -------------------
2019-01-06 15:43:47.566 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : student1.name=Frank Liu
2019-01-06 15:43:47.566 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : student1.address=Shanghai
2019-01-06 15:43:47.566 INFO 21612 --- [io-15000-exec-1] com.appjishu.swordboot.util.TestUtil : --testAppContextHolder done---
注意事项:
AppContextHolder在SpringBoot里使用,只需要在类名AppContextHolder
前标注@Component
如果在SpringMVC里使用的,需要用@Component标注类AppContextHolder, 并且在applicationContext.xml里面设置
包含AppContextHolder所在的package, 或者直接用bean
标签来注册它。