自定义SpringBoot Starter实现Morphia的自动配置

分类:
JAVA
标签:
SpringBoot
Mongo
Morphia
作者:
何鑫
创作时间:
2019/08/19 20:46:44

摘要:Morphia是基于官方Mongo驱动的Java操作类库,这一章我们将基于springboot建立一个自定义starter实现该框架的自动配置。

开箱即用的SpringBoot

SpringBoot自诞生依赖一直受到开发者追捧,一个重要的原因就是SpringBoot摆脱了原生Spring框架大量的xml配置,它遵循了“约定优先于配置”的原则,只需要很少配置(有时候甚至不需要配置)即可快速构建应用。它提供了针对企业应用开发各种场景的Starter,实现了各种框架的自动化配置,大大简化了框架的配置,真正实现了开箱即用。

MongoDB和Morphia

MongoDB是一个文档型数据库,相比于传统关系型数据库,它的优点是天生就拥有互联网基因。无schema模型使得它的数据结构更加灵活,减少了数据库数据结构修改带来的开销;自动化灾备提升了数据库的安全性;更简单的扩展伸缩提高了其可用性,降低了运维成本。Morphia是一个基于官方Mongo驱动的Java操作类库,它在官方驱动的基础上做了进一步的封装,简化了数据库操作。

自定义Starter实现Morphia自动配置

下面我们就来创建一个自定义Starter实现Morphia的自动配置,我们的目的是一个SpringBoot工程只要加入该Starter依赖,再加上少量的数据库配置信息即可实现对Mongo的基本操作。

第一步:创建普通Maven工程。工程名称为morphia-spring-boot-starter(第三方Starter推荐命名为xxx-spring-boot-starter)。

第二步:在POM文件中添加依赖。最终的POM文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.besthexin</groupId>
    <artifactId>morphia-spring-boot-starter</artifactId>
    <version>1.5.3.RELEASE</version>
    <name>morphia-spring-boot-starter</name>
    <description>morphia-spring-boot-starter</description>

    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>

    <dependencies>

        <!-- 用于支持xml和properties配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
            <version>2.1.7.RELEASE</version>
        </dependency>

        <!-- 用于支持自动配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.1.7.RELEASE</version>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <optional>true</optional>
        </dependency>

        <!-- morphia -->
        <dependency>
            <groupId>dev.morphia.morphia</groupId>
            <artifactId>core</artifactId>
            <version>1.5.3</version>
        </dependency>
    </dependencies>

</project>

第三步:创建配置类用于读取配置信息。

package cn.besthexin.morphia.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "morphia")
public class MorphiaConfig {

    /**
     * 需要扫描的包
     */
    private String mapPackage;

    /**
     * 要连接的数据库
     */
    private String dataBase;

    /**
     * 连接地址
     */
    private String host = "127.0.0.1";

    /**
     * 端口
     */
    private Integer port = 27017;

    /**
     * 账户认证数据库
     */
    private String authDataBase = "admin";

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

}

可以参考SpringBoot获取配置的三种方式

第四步:创建自动配置类

package cn.besthexin.morphia.config;


import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import dev.morphia.Datastore;
import dev.morphia.Morphia;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(MorphiaConfig.class)
public class MorphiaAutoConfiguration {

    private final MorphiaConfig morphiaConfig;

    public MorphiaAutoConfiguration(MorphiaConfig morphiaConfig) {
        this.morphiaConfig = morphiaConfig;
    }

    @Bean
    @ConditionalOnMissingBean(Datastore.class)
    public Datastore datastore() {
        Morphia morphia = new Morphia();
        if (morphiaConfig.getMapPackage() != null) {
            morphia.mapPackage(morphiaConfig.getMapPackage());
        }
        MongoClientOptions options = new MongoClientOptions.Builder().build();
        MongoClient mongoClient;
        if (morphiaConfig.getUsername() != null && morphiaConfig.getPassword() != null) {
            // 有密码连接
            MongoCredential credential = MongoCredential.createCredential(morphiaConfig.getUsername(), morphiaConfig.getAuthDataBase(), morphiaConfig.getPassword().toCharArray());
            mongoClient = new MongoClient(new ServerAddress(morphiaConfig.getHost(), morphiaConfig.getPort()), credential, options);
        } else {
            // 无密码连接
            mongoClient = new MongoClient(new ServerAddress(morphiaConfig.getHost(), morphiaConfig.getPort()));
        }
        Datastore datastore = morphia.createDatastore(mongoClient, morphiaConfig.getDataBase());
        // 为被@Indexed注解的所有字段创建索引
        datastore.ensureIndexes();
        return datastore;
    }

}

@Configuration 标记配置类

@EnableConfigurationProperties(MorphiaConfig.class) 使使用 @ConfigurationProperties 注解的类生效(即使MorphiaConfig能够注入)

@ConditionalOnMissingBean 当容器(Spring Context)中没有指定Bean的情况下进行自动配置

第五步:创建spring.factories。

我们还需要在resources下创建一个META-INF文件夹,在该文件夹中新建一个spring.factories文件,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.besthexin.morphia.config.MorphiaAutoConfiguration

创建该文件的目地是让SpringBoot启动时读取该文件,从而找到对应的配置类实现自动化配置。至此,一个简单的Stater便实现了。

第六步:安装到Maven仓库。

第七步:测试。

新建springboot工程,加入该依赖。

<dependency>
     <groupId>cn.besthexin</groupId>
      <artifactId>morphia-spring-boot-starter</artifactId>
      <version>1.5.3.RELEASE</version>
</dependency>

配置morphia:

morphia.auth-data-base=认证数据库
morphia.host=地址
morphia.port=端口号
morphia.data-base=操作数据库
morphia.username=账号
morphia.password=密码
morphia.map-package=需要扫描的包

新建model:

package cn.besthexin.morphia.model;

import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import lombok.Data;
import org.bson.types.ObjectId;

@Entity("user")
@Data
public class User {
    
    @Id
    private ObjectId _id;
    
    private String username;
    
    private String password;
    
}

@Entity 标记实体对应数据库文档

@Id 标记Id

在Test中注入Datastore,实现相关操作:

package cn.besthexin.morphia;

import cn.besthexin.morphia.model.User;
import dev.morphia.Datastore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MorphiaDemoApplicationTests {

    @Autowired
    private Datastore datastore;

    @Test
    public void contextLoads() {

        User user = new User();
        user.setUsername("hexin");
        user.setPassword("123456");
        datastore.save(user);

    }

}

运行测试:

成功,我们再看一下数据库有没有数据:

成功写入一条数据,我们的starter生效了!

morphia相关操作,请移步官网(英文):Morphia官网

starter码云地址:morphia-spring-boot-starter

感谢您的阅读,如有任何疑问,欢迎给我留言(在网站底部)。

发表评论

温馨提示: 评论先审核后发布, 请勿发表不良言论

所有评论