spring boot 整合thymeleaf+mysql+mongodb

目录:

 

1spring boot 整合thymeleaf

2spring boot 整合mysql

3spring boot 整合mongodb

4spring boot 整合其它

5、读取配置文件处理

 

在最近的新项目开发环境搭建过程中,经常会对比较独立的业务进行单独服务化部署。一个项目动辄会被拆分成十多个子系统(子服务),每个子系统都需要进行spring相关配置,无论是采用xml还是java配置方式,都比较繁琐有大量重复copy工作。

 

采用Srping boot可以大幅度减少依赖包配置,以及版本配置,部分bean可以根据约定的规则自动注入到spring容器(契约式编程),比如自动注入 视图解析器、数据源等等。在减少我们配置工作量的同时,让整个代码工程看起来更加简洁。

 

总的来说,spring boot主要采用了两种手段来减轻我们的配置工作量:

1、利用包依赖,其实也不是什么先进技术,就是把各个版本一致的jar包整合到一起。比如你只需要引入spring-boot-starter-thymeleaf,就可以自动引入spring mvc相关jar包,以及thymeleaf视图解析器相关jar包。

2、自动发现自动注入bean。比如spring boot启动时如果发现classpath下存在thymeleaf相关jar包,就会把thymeleaf做为视图解析器自动注入到spring容器,而无需我们手动配置。

 

下面分别来看下spring boot与各种常用工具的整合,文章末尾附整合代码github地址:

 

1spring boot 整合thymeleaf

 

Pom配置

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
</parent>
 
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

在顶级pom文件中配置parent,引入spring boot相关的依赖不再需要指定version

Spring boot会自动引入版本配套的springmvc 以及thymeleaf相关jar包,我们再也不用担心各个版本之间的兼容性问题,全部交由spring boot处理。

 

web容器中执行

Spring boot有两种启动方式:

1、通过java –jar运行,spring boot内部自动tomcat web容器,工程打包指定为jar即可。

2、部署到外部tomcat web容器,工程打包指定为war包即可。

由于已经习惯采用war包部署方式,这里在pom文件中指定为war包:

<packaging>war</packaging>

 

指定启动类,内容如下:

//@Configuration 配置类,类似xml
//@EnableAutoConfiguration  启动自动查找配置
//@ComponentScan  扫描自定包
@SpringBootApplication
public class BootTestInitializer extends SpringBootServletInitializer{
 
    /**
     * 让spring boot在tomcat中运行
     * @param builder
     * @return
     */
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(BootTestInitializer.class);
    }
 
    public static void main(String[] args) {
        SpringApplication.run(BootTestInitializer.class, args);
    }
}
 

 

Spring boot启动类继承自SpringBootServletInitializer 类,定义main方法可以实现java –jar执行,如果要在web容器中执行必须重写protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)方法。

 

@SpringBootApplication注解相当于三个注解的集合:

1@Configuration:表示该启动类为配置类(类似xml配置文件),可以通过@bean注解在该类中手动注入beanspring容器。

2@EnableAutoConfigurationspring boot启动自动配置(契约式编程)

3 @ComponentScan:自动扫描该启动类目录,以及其子目录下 @Component标记的类,自动实例化并注入到spring 容器。

 

添加拦截器和静态资源

通过继承WebMvcConfigurerAdapter,重写addInterceptors方法可以实现拦截器添加,重写addResourceHandlers实现静态资源重定位,具体实现如下:

 

//定义拦截器
public class MyInterceptor implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //验证权限,使用ThreadLocal等
        System.out.println("preHandle:在Controller之前调用,权限验证");
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle:在Controller之后调用");
    }
 
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        //清除ThreadLocal等
        System.out.println("afterCompletion:在视图渲染完成之后调用");
    }
}
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
 
    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addInterceptor方法 可以加入多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则
        // excludePathPatterns 用户排除拦截规则
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
 
    /**
     * 指定css,js等静态资源路径
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css")
                .addResourceLocations("classpath:/mystatic/");
}
 
}
 

 

Spring boot的默认资源路径跟springmvc不同,webapp不再是其默认资源路径,默认资源路径变为:/META-INF/resources//resources/ /static/ /public/。但我们可以通过重新addResourceHandlers方法进行更改,如上述代码所示。

 

thymeleaf 视图解析器配置

spring boot默认会自动读取classpath下的application. properties(application.yml)thymeleaf相关的配置内容如下:

#thymeleaf 配置(用于自动注入 TemplateResolver)
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
 

 

spring boot启动时发现thymeleaf相关jar包已经在classpath下,会自动注入thymeleaf视图解析器,需要的配置会自动从application.properties配置文件中获取:凡是以spring.thymeleaf开头的属性配置,会在初始化thymeleaf视图解析器时自动使用。

 

创建TestController thymeleaf模板文件hello.htmlspring bootthymeleaf整合完成,最终的代码结构如下:




到这里 spring bootthymeleaf的整合完成,只需三步即可以完成:

1、引入spring-boot-starter-thymeleaf这个依赖

2、把thymeleaf需要的配置写入application.properties

3、创建spring boot启动类

 

2spring boot 整合mybatismysql

 

生产环境一般都会用连接池,这里以mybatis整合dbcp2连接池,连接mysql数据库为例。

首先看下pom.xml配置,只需引入三个依赖:

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
        </dependency>
 

 

然后在application. properties中进行:mybatis配置、mysql数据源配置、dbcp2连接池配置。

 

#mybatis配置(其他属性查看MybatisProperties成员变量)
mybatis.type-aliases-package=com.sky.boot.domain.mysql
mybatis.mapper-locations=classpath:mapper/**/*Mapper.xml
 
 
#mysql数据源配置(其他属性查看DataSourceProperties成员变量)
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql:loadbalance://192.168.0.100:3306/test_dec?useUnicode=true&amp;characterEncoding=UTF8
spring.datasource.username = test
spring.datasource.password = test
 
#dbcp2连接池配置(其他属性查看BasicDataSource成员变量)
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.initial-size=5
spring.datasource.dbcp2.min-idle=5
spring.datasource.dbcp2.max-idle=10
spring.datasource.dbcp2.max-total=30
 

 

spring boot中整合mybatis+dbcp2连接池+mysql,需要你做的也就这么多了。Spring boot发现classpath路径下有mybatisdbcp、以及mysql jdbc相关的jar包,会自动注入数据库连接池相关的dbcp mysql连接池、并自动与mybastis整合。

 

这里笔者还采用mybatis自动生成代码工具mybatis-generator,自动生成mybatis xml配置、数据库表vomybatis mapper接口。具体代码从文章末尾的github地址中获取。

 

另外为了配合使用自动生成的mybatis代码,还需要在spring boot启动类中添加mapper接口扫描注解@MapperScan,在程序启动时 该注解会扫描指定路径下的mapper接口类,并自动为其生成实现类注入到spring 容器,如下:

 

@SpringBootApplication
@MapperScan("com.sky.boot.dao.mysql")
public class BootTestInitializer extends SpringBootServletInitializer{
     //省略代码
}
 

 

到这里spring bootmybatisdbcp mysql数据库连接池整合完毕,需要我们做的也就是添加需要的jar包,并把相关的配置添加到application. properties配置文件

 

3spring boot 整合mongodb

 

按照整合套路,首先引入mongodb相关的jar包,其实只需要一个依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
 

 

然后在application. properties配置文件中添加相关配置:

#mongdb相关配置(其他属性查看MongoProperties成员变量)
spring.data.mongodb.host=192.168.0.100
spring.data.mongodb.port=27017
spring.data.mongodb.database=mongodb_test
spring.data.mongodb.username=passport
spring.data.mongodb.password=passport
 

 

整合mongodb需要我们做的也就这么多了,其它工作全部交给spring boot即可。

 

下列来看一个使用mongodb的案例,这里模拟一个订单的生成和查询,订单类Order 里面包含多个商品product,如下:

@Document(collection="order_info")
public class Order {
 
    @Id
    private String id;
 
    @Field("client")
    private String customer;
 
    private String desc;
 
    private Collection<Product> products = new LinkedHashSet<Product>();
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getCustomer() {
        return customer;
    }
 
    public void setCustomer(String customer) {
        this.customer = customer;
    }
 
    public String getDesc() {
        return desc;
    }
 
    public void setDesc(String desc) {
        this.desc = desc;
    }
 
    public Collection<Product> getProducts() {
        return products;
    }
 
    public void setProducts(Collection<Product> products) {
        this.products = products;
    }
 
    public void put(Product product){
        this.products.add(product);
    }
}

 

 
public class Product {
    private Long id;
 
    private String name;
 
    private double price;
 
    private int num;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public double getPrice() {
        return price;
    }
 
    public void setPrice(double price) {
        this.price = price;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
}
 

 

@Document(collection="order_info")注解表示Order类对应的是一个mongodb中的文档,文档的名称为"order_info"(可以理解为mysql中的表)。

 

然后使用spring data mongodb Repository定义一个操作该文档的接口类:

public interface OrderRepository extends MongoRepository<Order,String> {
 
}

Controller中,使用OrderRepositorymongodb中添加和查询订单信息:

@Controller
@RequestMapping("/")
public class TestController {
 
    @Resource
    private OrderService orderService;
 
    @RequestMapping("/mongodb")
    public String mongdb(Map<String,Object> map){
        Order order = new Order();
        order.setId("10000");
        order.setCustomer("zhang san");
        order.setDesc("一个订单");
 
        Product p1 = new Product();
        p1.setId(1111l);
        p1.setName("小鸡手机");
        p1.setPrice(1000);
        p1.setNum(1);
 
        Product p2 = new Product();
        p2.setId(2222l);
        p2.setName("小小鸡手机");
        p2.setPrice(1000);
        p2.setNum(1);
 
        order.put(p1);
        order.put(p2);
        orderService.save(order);
 
        Order o1=orderService.getOrder("10000");
        map.put("order",o1);
 
        return "mongdb";
    }
}
 

 

使用MongoVUE可以化工具查看 刚才插入的Order记录:



 

 

比直接使用mongoTemplate操作起来简单了很多。

 

spring boot 整合其它

 

通过上述的讲解,也许大家已经发现了,对应spring boot已经整合的常用框架,我们可以直接引入相关的spring boot jar依赖,并配置application. properties配置文件即可。具体spring boot已经整合了那些框架(或者说组件),可以参考spring boot官方文档:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-connecting-to-mongodb,打开该链接页面的最末尾。

 

对于spring boot没有实现自动整合的框架,我们可以通过java bean配置的方式,把所需的bean注入spring容器。

 

这里以模拟整合dubbo rpc框架为例:

首先:引入dubbo相关的jar包(这里只是模拟,没有真实引入)。

然后:配置application. properties配置文件,内容如下:

#dubbo相关配置,假设只需要下列两个配置
dubbo.zkAddress=xxxxxxxx
dubbo.alias=test-group

 

 

最后:新建一个 spring bean配置类:

@Configuration
@ConfigurationProperties(prefix = "dubbo")
public class DubboConfig {
 
    private String zkAddress;
 
    private String alias;
 
    @Bean
    public OneService oneService(){
        OneService oneService= new OneService(zkAddress,alias);
        return oneService;
    }
 
    public void setZkAddress(String zkAddress) {
        this.zkAddress = zkAddress;
    }
 
    public void setAlias(String alias) {
        this.alias = alias;
    }
}
 

 

通过@ConfigurationProperties(prefix = "dubbo")注解,spring boot会自动读取application. properties配置文件中,前置为dubbo的配置,并把前面配置的两个数据,自动复制给zkAddressalias。然后通过@Bean注解的oneService()方法,会生成一个单例的OneService对象 并注入到spring容器。在需要使用该Service的地方,直接通过@Resource(@ Autowired)注解注入 即可使用。

 

@Controller
@RequestMapping("/")
public class TestController {

    @Resource
    private OneService oneService;

   
    @RequestMapping("/dubbo")
    public String dubbo(Map<String,Object> map){
        map.put("dubbo",oneService.getPrice());
        return "dubbo";
    }
}
 

 

这里只是模拟整合注入Dubbo,注入一个DubboService。其实采用这种方式可以完成,各种自定义框架的注入,唯一需要多处理的就是添加一个配置类(跟springxml配置方式等效)。

 

5、读取配置文件处理

 

springjava bean中使用.properties配置文件中的属性,有两种方式:

 

1java bean中,使用spring中的Environment

首先采用xml配置placeholder <context:property-placeholder location="classpath:xxxx.properties" />

 

使用方式

@Resource
Environment env;
 
//省略
String value =env.containsProperty("key");
//省略

 

2、使用@Value注解

跟前一种方式一样,首先采用xml配置placeholder <context:property-placeholder location="classpath:xxxx.properties" />

 

java bean的属性或者参数上使用@Value注解

 

@Value( "${key}" )
private String value;
 

 

两种方式中的xml配置方式,可以改为java bean配置方式,使用@PropertySource注解:

@Configuration
@PropertySource("classpath:xxxxx.properties")
public class PropertiesConfig {
 
   @Bean
   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      return new PropertySourcesPlaceholderConfigurer();
   }
}
 

 

3、spring boot中使用配置

 

最后再来看下 spring boot读取配置的方式,spring boot会默认自动读取application. propertiesapplication.yml配置文件。自定义的属性key不要覆盖spring boot默认的整合的key,比如spring.datasource.*,这种开头的keyspring boot会默认读取出来生成数据源使用。本周上述内容都是以application. properties进行讲解,其实application.yml看起更简洁些:

spring:
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql:loadbalance://192.168.0.100:3306/test_dec?xxxxxxx
    username: test
    password: test
 

 

@ConfigurationProperties注解不指定配置文件,会默认读取application. propertiesapplication.yml。但如果application. propertiesapplication.yml在同一目录下使用,application.yml不会生效(不同目录下有优先级先后顺序,个人觉得不必去深究,实际运用中二选一即可)。

 

通过@ConfigurationProperties注解的bean中,可以把值自动注入到对应的成员变量,但必须要有setter方法;也可以用@Value注解获取,可以不用实现setter方法,如下zkAddressalias都可以被注入:

@Configuration
@ConfigurationProperties(prefix = "dubbo")
public class DubboConfig {
 
    private String zkAddress;
   
    @Value("${alias}")
private String alias;
 
public void setZkAddress(String zkAddress) {
        this.zkAddress = zkAddress;
    }
}
 

 

对于自定义的.properties文件,也可以通过@ConfigurationProperties注解进行指定读取:

@Configuration
@ConfigurationProperties(value=" classpath:xxxxx.properties",prefix = "dubbo")
public class DubboConfig {
     //省略代码
}
 

 

也就是说在spring boot java bean中读取配置文件,除了前面提到的两种方式,还提供第三种方式:@ConfigurationProperties注解,在spring boot中也推荐使用@ConfigurationProperties注解方式。

 

最后文章讲解的代码地址:https://github.com/gantianxing/boot-test.gitapplication.properties配置文件中的mysqlmongo相关信息 替换成自己的,即可启动直接运行。

猜你喜欢

转载自moon-walker.iteye.com/blog/2389231