面试官:小伙子,你给我说一下SpringBoot怎么整合UidGenerator吧

一、基本概述

1.SpringBoot整合百度开源UidGenerator 并且替换默认的xml映射的方式为MyBatisPlus 2.SpringBoot版本为 2.2.8.RELEASE;MyBatisPlus版本为 3.3.2;UidGenerator版本为1.0.0-SNAPSHOT 3.替换默认的work_node 表结构和对应的实体类 4.替换默认的DisposableWorkerIdAssigner 并且修改注入的mapper接口为service接口

二、依赖及版本

注意事项: 由于UidGenerator 默认依赖了MyBatis 和MyBatis Spring相关依赖,在这使用的是MyBatisPlus,因此要把MyBatis 和MyBatis Spring的依赖排除。

<dependency>
	<groupId>com.baidu.fsg</groupId>
	<artifactId>uid-generator</artifactId>
	<version>${uid-generator.version}</version>
	<exclusions>
		<exclusion>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
		</exclusion>
		<exclusion>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>${mybatis-plus.version}</version>
</dependency>

复制代码

三、表结构及实体类替换

CREATE TABLE `sy_worker_node`  (
  `work_node_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `host_name` varchar(64)  NOT NULL COMMENT '主机名称',
  `port` varchar(64)  NOT NULL COMMENT '端口',
  `type` int(11) NOT NULL COMMENT '类型(ACTUAL or CONTAINER)',
  `launch_date` date NOT NULL COMMENT '年月日',
  `modeified` timestamp(0) NOT NULL  COMMENT '修改时间',
  `created` timestamp(0) NOT NULL  COMMENT '创建时间',
  PRIMARY KEY (`work_node_id`) USING BTREE
) ;

复制代码
@TableName("sy_worker_node")
@Getter
@Setter
public class WorkNode {

	@TableId(value = "work_node_id",type = IdType.AUTO)
	private Long work_node_id;

	@TableField(value = "host_name")
	private String host_name;

	@TableField(value = "port")
	private String port;

	@TableField(value = "type")
	private Integer type;

	@TableField(value = "launch_date")
	private Date launch_date;

	@TableField(value = "modeified")
	private Date modeified;

	@TableField(value = "created")
	private Date created;

}

复制代码

四、mapper接口

@Mapper
public interface WorkerNodeMapper extends BaseMapper<WorkNode>{

}

复制代码

五、接口及实现类

public interface IWorkNodeService extends IService<WorkNode>{

	public WorkNode getWorkerNodeByHostPort(String host,String port);

	public void addWorkerNode(WorkNode workNode);
}

复制代码
@Service("workNodeService")
public class WorkNodeServiceImpl extends ServiceImpl<WorkerNodeMapper, WorkNode> implements IWorkNodeService{

	@Override
	public WorkNode getWorkerNodeByHostPort(String host, String port) {
		QueryWrapper<WorkNode> queryWrapper=new QueryWrapper<>();
		queryWrapper.lambda().eq(WorkNode::getHost_name, host).eq(WorkNode::getPort, port);
		return getOne(queryWrapper);
	}

	@Override
	public void addWorkerNode(WorkNode workNode) {
		workNode.setCreated(new Date());
		workNode.setModeified(new Date());
		save(workNode);
	}

}

复制代码

六、UidGenerator的配置类

@Configuration
public class IdGeneratorConfiguration {
	/*
		该类是在默认的基础上修改的
	*/
	@Bean
	public DisposableWorkerIdAssigner disposableWorkerIdAssigner() {
		return new DisposableWorkerIdAssigner();
	}
	//默认注入的id生成器,使用时只需从容器取即可
	@Bean
	public CachedUidGenerator cachedUidGenerator() {
		CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
		cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner());
		return cachedUidGenerator;
	}

}

复制代码
public class DisposableWorkerIdAssigner implements WorkerIdAssigner {
    private static final Logger LOGGER = LoggerFactory.getLogger(DisposableWorkerIdAssigner.class);
    /*
    @Autowired
    private WorkerNodeMapper workerNodeMapper;

    */
    //修改默认注入mapper为service接口
    @Autowired
    private IWorkNodeService workNodeService;

    /**
     * Assign worker id base on database.<p>
     * If there is host name & port in the environment, we considered that the node runs in Docker container<br>
     * Otherwise, the node runs on an actual machine.
     * 
     * @return assigned worker id
     */
    @Transactional
    public long assignWorkerId() {
        // build worker node entity
    	WorkNode workNode = buildWorkerNode();

        // add worker node for new (ignore the same IP + PORT)
        workNodeService.addWorkerNode(workNode);
        LOGGER.info("Add worker node:" + workNode);

        return workNode.getWork_node_id();
    }

    /**
     * Build worker node entity by IP and PORT
     */
    private WorkNode buildWorkerNode() {
    	WorkNode workNode = new WorkNode();
        if (DockerUtils.isDocker()) {
        	workNode.setType(WorkerNodeType.CONTAINER.value());
        	workNode.setHost_name(DockerUtils.getDockerHost());
        	workNode.setPort(DockerUtils.getDockerPort());
        	workNode.setLaunch_date(new Date());

        } else {
        	workNode.setType(WorkerNodeType.ACTUAL.value());
        	workNode.setHost_name(NetUtils.getLocalAddress());
            workNode.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(100000));
            workNode.setLaunch_date(new Date());
        }

        return workNode;
    }

}

复制代码

七、测试类

@RestController
public class IndexController {
	//从容器中获取在配置类中注入的实例
	@Autowired
	private UidGenerator uidGenerator;

	@GetMapping("/index")
	public String index(){
		System.err.println(uidGenerator.getUID());
		return "success";
	}
}

复制代码

测试结果:

八、总结

  1. 首先要创建相关的表结构 每次启动服务会插入一条数据
  2. 替换默认的DisposableWorkerIdAssigner 并且修改注入的实例
  3. 在配置类中注入id的生成器及所需要的实例

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

猜你喜欢

转载自juejin.im/post/5f2107bff265da22bb7b4d27