使用IDEA创建一个简单的SpringBoot项目(二)


此文基于:使用IDEA创建一个简单的SpringBoot项目(一)

静态模板FreeMarker

新建一个项目或者module,名称FreeMarker

修改build.gradle:

group 'lckiss.com'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
//war
apply plugin: 'war'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile("org.springframework.boot:spring-boot-starter-web")

    //freemarker模板引擎jar包
    compile("org.springframework.boot:spring-boot-starter-freemarker")
}

bootJar {
    baseName = 'gs-spring-boot'
    version =  '0.1.0'
}

一个启动入口:

package com.lckiss.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

/**
 * 启动方式一 ComponentScan扫描Controller位置
 */@EnableAutoConfiguration
@ComponentScan(basePackages = "com/lckiss/controller")
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

}

一个访问路由:

package com.lckiss.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Controller
public class HelloController {

    @RequestMapping("/")
    @ResponseBody
    public String index() {
        return "Greetings from Spring Boot!";
    }

    //默认模板引擎
    @RequestMapping("/home")
    public String home() {
        return "index";
    }

    //模板引擎-数据渲染
    @RequestMapping("/data")
    public String data(HttpServletRequest request) {
        request.setAttribute("name","lckiss");

        List<String> userList=new ArrayList<String>();
        userList.add("张三");
        userList.add("李四");
        userList.add("王二");
        userList.add("麻子");

        request.setAttribute("userList",userList);
        return "data";
    }
}

在resources目录下创建application.properties,内容(其实这些都是默认值):

spring.freemarker.template-loader-path=classpath:/templates
spring.freemarker.suffix=.ftl
spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false

可以看到,该模板的后缀结尾为.ftl,文件夹为templates,所以在resources新建一个templates文件夹,里面放两个.ftl文件,分别对应访问路由中的index与data。一个是字符串,一个是列表对象。

data.ftl:

<!DOCTYPE html>
<html>
<head>
    <title>title</title>
</head>
<body>
this is a freemarker page!!!
get data : ${name}
<br>
List data:
<#list userList as user>
    ${user} <br>
</#list>
</body>
</html>

index.ftl:

<!DOCTYPE html>
<html>
<head>
    <title>title</title>
</head>
<body>
this is a freemarker page!!!
</body>
</html>

试着去访问http://localhost:8080/data与http://localhost:8080/

你会得到你想要的结果。

访问静态资源

将1.jpg(不提供)按传统的方式放到webapp/image下面是可以通过http://localhost:8080/image/1.jpg正常访问的。但是对于新东西,肯定有新做法:

默认spring-boot的静态资源都是放在resources目录下的。并且给定了4个文件夹,分别为

/META-INF/resources

/resources

/static

/public

你可以尝试新建这些文件夹,然后通过链接去访问(链接访问时,不需要加上文件夹名,比如图片在/resources/static/1.jpg,只需要输入http://localhost:8080/1.jpg即可)。

如果每个文件夹中都有同一个文件,那么就会按优先级去读取META-INF/resources>resources>static>public

当然你可以选择覆盖默认的配置,在application.properties中加入即可

#基于默认大于配置的原则,不建议开启自定义的静态访问路径
spring.mvc.static-path-pattern=/resources/**

集成log4j2

先集成依赖:

//去除logging 添加部分
configurations {
    all*.exclude module : 'spring-boot-starter-logging'
}

dependencies {
...
//log4j2
compile("org.springframework.boot:spring-boot-starter-log4j2")
...

在application.properties中添加:

#log
logging.config= classpath:log4j2.properties

并在application.properties同目录下创建log4j2.properties:

status = error
name = PropertiesConfig

property.filename = target/rolling/rollingtest.log

filters = threshold

filter.threshold.type = ThresholdFilter
filter.threshold.level = debug

rootLogger.level = info

#尽量不要输出到console,要养成看日志文件的习惯
#使用其中一个方案时 另一个需要注释
#不使用控制台输出 方案一
rootLogger.appenderRefs =I,E
appenders =I, E

#使用控制台输出 方案二
#rootLogger.appenderRefs = stdout,I,E
#rootLogger.appenderRef.stdout.ref = STDOUT
#appenders = console, I, E
#appender.console.type = Console
#appender.console.name = STDOUT
#appender.console.target = SYSTEM_OUT
#appender.console.layout.type = PatternLayout
#appender.console.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ] %m%n

#记录的info文件
rootLogger.appenderRef.I.ref = InfoRollingFile
rootLogger.appenderRef.I.level = info

#记录的error文件
rootLogger.appenderRef.E.ref = ErrorRollingFile
rootLogger.appenderRef.E.level = error

#对应appenderRef.I.ref = InfoRollingFile
appender.I.type = RollingFile
appender.I.name = InfoRollingFile
appender.I.fileName = ./logs/info.log
appender.I.filePattern = ./logs/info_%d{yyyy-MM-dd}_%i.log
appender.I.layout.type = PatternLayout
appender.I.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ] %m%n
appender.I.policies.type = Policies
appender.I.policies.time.type = TimeBasedTriggeringPolicy
appender.I.policies.time.interval = 1
appender.I.policies.time.modulate = true
appender.I.policies.size.type = SizeBasedTriggeringPolicy
appender.I.policies.size.size=20M
appender.I.strategy.type = DefaultRolloverStrategy
appender.I.strategy.max = 100

#对应appenderRef.E.ref = ErrorRollingFile
appender.E.type = RollingFile
appender.E.name = ErrorRollingFile
appender.E.fileName = ./logs/error.log
appender.E.filePattern = ./logs/error_%d{yyyy-MM-dd}_i.log
appender.E.layout.type = PatternLayout
appender.E.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ] %m%n
appender.E.policies.type = Policies
appender.E.policies.time.type = TimeBasedTriggeringPolicy
appender.E.policies.time.interval = 1
appender.E.policies.time.modulate = true
appender.E.policies.size.type = SizeBasedTriggeringPolicy
appender.E.policies.size.size=20M
appender.E.strategy.type = DefaultRolloverStrategy
appender.E.strategy.max = 100

在controller中添加路由:

private final static Logger logger=org.slf4j.LoggerFactory.getLogger(HelloController.class);

//log演示
@RequestMapping("/log")
@ResponseBody
public String log(String name) {
 logger.info("----this is a log4j2 log-----");
 logger.info("----name is "+name+"--------");
 return name;
}

重启服务器,在地址栏输入http://localhost:8080/log?name=test,你将会在此处看到你的log文件与内容

Spring-boot多数据源

PS:对于SB2.0,这里大把坑,值得注意下,基本上 我的一下午就没了。多数据源,一定要区分主从,主用@Primary标记,从不要标记。jdbc的url改用jdbc-url

根据上面的项目继续,添加依赖:

//配置mybatis
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2")
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter-test:1.3.2")

//mysql驱动
compile 'mysql:mysql-connector-java'

在HelloController中添加下面两个路由 Autowired是自动注入

//访问多数据源中的第一个数据源
@Autowired
private MasterMapper masterMapper;

@RequestMapping("/master")
@ResponseBody
public String master(int id) {
    User user= masterMapper.selectUserById(id);
    return user.getName();
}


//访问多数据源中的第二个数据源
@Autowired
private SlaveAlphaMapper slaveAlphaMapper;

@RequestMapping("/slaveAlpha")
@ResponseBody
public String slaveAlpha(int id) {
   User user= slaveAlphaMapper.selectUserById(id);
    return user.getName();
}

主数据源:

package com.lckiss.datasource;

import ...

@Configuration
//扫描指定包下的mapper
@MapperScan(basePackages = "com.lckiss.mapper.master",sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class DatasourceFirstConfig {

    //第一步:声明一个数据源master  @Primary优先使用该注解的bean
    @Bean(name = "master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    @Primary
    public DataSource masterDataSource(){
        return DataSourceBuilder.create().build();
    }

    //第二步:设置SqlSessionFactory @Qualifier是用于指定bean,需要时会查找该bean然后返回需要的对象
    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master")DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean=new SqlSessionFactoryBean();
        //设置数据源
        sessionFactoryBean.setDataSource(dataSource);
        return sessionFactoryBean.getObject();
    }

    //第三步:创建事务管理
    @Bean(name = "masterDataSourceTransactionManager")
    @Primary
    public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("master")DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    //第四步:创建masterSqlSessionTemplate
    @Bean(name = "masterSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

从数据源:

package com.lckiss.datasource;

import ...

//扫描指定包下的mapper
@Configuration
@MapperScan(basePackages = "com.lckiss.mapper.slave",sqlSessionTemplateRef = "slaveAlphaSqlSessionTemplate")
public class DatasourceSecondConfig {
    //第一步:声明一个数据源slaveAlpha   
    @Bean(name = "slaveAlpha")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveAlphaDataSource(){
        return DataSourceBuilder.create().build();
    }

    //第二步:设置SqlSessionFactory @Qualifier是用于指定bean,需要时会查找该bean然后返回需要的对象
    @Bean(name = "slaveAlphaSqlSessionFactory")
    public SqlSessionFactory slaveAlphaSqlSessionFactory(@Qualifier("slaveAlpha")DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean=new SqlSessionFactoryBean();
        //设置数据源
        sessionFactoryBean.setDataSource(dataSource);
        return sessionFactoryBean.getObject();
    }

    //第三步:创建事务管理
    @Bean(name = "slaveAlphaDataSourceTransactionManager")
    public DataSourceTransactionManager slaveAlphaDataSourceTransactionManager(@Qualifier("slaveAlpha")DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    //第四步:创建slaveAlphaSqlSessionTemplate
    @Bean(name = "slaveAlphaSqlSessionTemplate")
    public SqlSessionTemplate slaveAlphaSqlSessionTemplate(@Qualifier("slaveAlphaSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

来两个mapper,分别对应主从数据源:

package com.lckiss.mapper.master;

import ...

public interface MasterMapper {
    @Insert("insert into user(name) values(#{name})")
    void insertUser(@Param("name") String name);

    @Select("select * from user where id=#{id}")
    User selectUserById(@Param("id") Integer id);
}

从:

package com.lckiss.mapper.slave;

import ...

public interface SlaveAlphaMapper {
    @Insert("insert into user(name) values(#{name})")
    void insertUser(@Param("name") String name);

    @Select("select * from user where id=#{id}")
    User selectUserById(@Param("id") Integer id);
}

实体:

package com.lckiss.model;

public class User {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

启动入口改为:

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

}

application.properties中添加:

#第一个数据源
spring.datasource.master.jdbc-url = jdbc:mysql://localhost:3306/SpringBoot?useUnicode=true&characterEncoding=utf-8
spring.datasource.master.username = root
spring.datasource.master.password = mysql
spring.datasource.master.driverClassName = com.mysql.jdbc.Driver

#第二个数据源
spring.datasource.slave.jdbc-url = jdbc:mysql://localhost:3306/SpringBoot?useUnicode=true&characterEncoding=utf-8
spring.datasource.slave.username = root
spring.datasource.slave.password = mysql
spring.datasource.slave.driverClassName = com.mysql.jdbc.Driver

好了,去跑吧,应该是没问题的,半夜了才找到原因,我也是醉了,对于一个新手,课程是eclipse+maven,我用idea+gradle,资料少得可怜,好在,折腾折腾就慢慢理解了。

源代码下载:https://github.com/TIL-MICE/SpringBoot

声明:TIL|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA[ZH]协议进行授权

转载:转载请注明原文链接 - 使用IDEA创建一个简单的SpringBoot项目(二)


Life is very interesting. In the end, some of your greatest pains become your greatest strengths.