最近没什么事,所以看一下spring boot这个微服务框架。首先当然是跑去官网看一下demo,真的是简单!如下:
就这么些,一个springboot 的Hello World Demo 就完成了!
springboot 把我们从springmvc众多的xml文件里解救了出来,接下来就开始搭建吧。我这里使用IDEA,没办法,eclipse太丑了,颜控
首先来看下我的项目目录结构:
第一步创建maven项目
填写GroupId和ArtifactId
再添加一下这个东西。然后下一步填上项目名finish
接下来就是pom.xml的配置了,附上完整pom代码,(里面有一些是我项目需要的包,根据自己需要删除即可)
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>springboot</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>springboot Maven Webapp</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.3.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.7</java.version> <jackson.version>1.9.7</jackson.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--支持使用 JDBC 访问数据库--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <!--Mysql / DataSource--> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--Json Support--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.15</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <!--<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>--> <!-- 日志管理 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!-- Base64处理图片包 --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency> <!-- https://mvnrepository.com/artifact/cn.featherfly/bccs-api --> <dependency> <groupId>cn.featherfly</groupId> <artifactId>bccs-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>com.belerweb</groupId> <artifactId>pinyin4j</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>eu.bitwalker</groupId> <artifactId>UserAgentUtils</artifactId> <version>1.17</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <compilerVersion>1.7</compilerVersion> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
接下来在recourse目录下创建application.properties资源文件:
spring.dataSource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=convertToNull spring.dataSource.username=root spring.dataSource.password=123456 spring.dataSource.driver-class-name=com.mysql.jdbc.Driver server.address=127.0.0.1 server.port=8080
server.port指定端口
接下来创建项目入口,就是前面demo中的Application
package com.rental; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.tomcat.jdbc.pool.DataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import java.util.ArrayList; import java.util.List; /** * Created by demo on 2017/5/25. */ //@EnableAutoConfiguration //@Configuration //@ComponentScan @SpringBootApplication // 等价上面三个注解 @MapperScan("com.rental.mapper")//mybatis映射接口的路径 public class Application { private static Logger logger = LoggerFactory.getLogger(Application.class); /**启动方法*/ public static void main(String[] args){ SpringApplication.run(Application.class,args); logger.info("----------Application is running----------"); } /** * 配置数据源 * @return */ @Bean @ConfigurationProperties(prefix = "spring.dataSource") public DataSource dataSource(){ return new DataSource(); } /** * 提供SqlSession * @return */ @Bean public SqlSessionFactory sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource()); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //mybatis 映射文件路径 sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mybatis/**.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } /** * 将返回结果以json返回 * @return */ @Bean public HttpMessageConverters fastJsonHttpMessageConverters(){ //1.需要定义一个convert转换消息的对象; FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); //2:添加fastJson的配置信息; FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty); //3处理中文乱码问题 List<MediaType> fastMediaTypes = new ArrayList<>(); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); //4.在convert中添加配置信息. fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes); fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); HttpMessageConverter<?> converter = fastJsonHttpMessageConverter; return new HttpMessageConverters(converter); } }
开始碰到启动以后访问不到,我猜测原因是这个启动的类要放到根目录下,反正注意一下吧,大家也可以测试一下。顺便告知下原因
接下来配置mybatis的映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.rental.mapper.user.UserMapper"> <resultMap id="BaseResultMap" type="com.rental.mapper.user.dataobject.UserDO"> <id column="id" property="userId" jdbcType="BIGINT"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> <result column="password" property="password" jdbcType="VARCHAR"/> <result column="access_token" property="accessToken" jdbcType="VARCHAR"/> </resultMap> <select id="findUserByUserId" resultMap="BaseResultMap" parameterType="java.lang.Long"> SELECT id,name,age,password,access_token FROM user WHERE id=#{userId,jdbcType=BIGINT}; </select> </mapper>
再一个对应的接口:
public interface UserMapper {
UserDO findUserByUserId(Long userId);
}
紧接着就是一个controller
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserProcess process;
@RequestMapping(value ="/info",method = RequestMethod.GET)
@ResponseBody
public UserModel findUserByUserId(UserIdParam param){
return process.findUserByUserId(param);
}
}
process中的具体实现就不贴了,整个流程就是如此
最后运行 Application.java,再到浏览器中访问localhost:8080/user/info?userId=1 即可
整个流程到此结束
最后附上日志管理:log.properties
### set log level all ###
log.loggingLevel.all=info
### set log level rest ###
log.loggingLevel.rest=info
### set log root ###
log.loggingRoot=/home/rental/logs
log4j.appender.appender1=org.apache.log4j.ConsoleAppender
这里的log.loggingRoot=/home/rental/logs 就是日志文件的保存路径,相对于idea的路径
logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="5 seconds" debug="false"> <property scope="LOG_HOME" resource="log.properties" /> <contextName>rental-service</contextName> <jmxConfigurator /> <!-- direct log messages to stdout --> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.out</Target> <encoder> <pattern>%d{HH:mm:ss.SSS} [%t] %highlight(%-5p) %green(|-%c{35}:%L) %white - %m %n</pattern> </encoder> </appender> <appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.loggingRoot}/rental-service.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${log.loggingRoot}/%d{yyyy-MM,aux}/rental-service.log.%d.%i.gz</FileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>1024MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>10</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss}[%t]%-5p %c{36}.%M(%L) %m%n</pattern> </encoder> </appender> <appender name="REST" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.loggingRoot}/rental-service-rest.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${log.loggingRoot}/%d{yyyy-MM,aux}/rental-service-rest.log.%d.%i.gz</FileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>1024MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>10</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss}[%t]%-5p %c{36}.%M(%L) %m%n</pattern> </encoder> </appender> <appender name="ASYNCConsole" class="ch.qos.logback.classic.AsyncAppender"> <includeCallerData>true</includeCallerData> <appender-ref ref="stdout" /> </appender> <!-- 定义Spring日志 --> <logger name="org.springframework" level="${log.loggingLevel.all}" additivity="false"> <appender-ref ref="ALL" /> </logger> <logger name="com.rental" level="${log.loggingLevel.all}" additivity="false"> <appender-ref ref="ALL" /> </logger> <!-- 定义rest日志 --> <logger name="rest" level="${log.loggingLevel.rest}" additivity="false"> <appender-ref ref="REST" /> </logger> <root level="${log.loggingLevel.all}"> <appender-ref ref="ALL" /> </root> </configuration>
6.2新增定时任务:
在启动入口或者另写一个配置文件加上注解 @EnableScheduling。在要调度的方法上加上注解 @Scheduled
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); //每3秒执行一次 @Scheduled(fixedRate = 3000) public void timerRate() { System.out.println(sdf.format(new Date())); } //第一次延迟1秒执行,当执行完后3秒再执行 @Scheduled(initialDelay = 1000, fixedDelay = 3000) public void timerInit() { System.out.println("init : "+sdf.format(new Date())); }
cron表达式
Spring 定时任务之 @Scheduled cron表达式 http://biaoming.iteye.com/blog/39532 一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。 按顺序依次为 秒(0~59) 分钟(0~59) 小时(0~23) 天(月)(0~31,但是你需要考虑你月的天数) 月(0~11) 天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT) 7.年份(1970-2099) 其中每个元素可以是一个值(如6),一个连续区间(9-12),一个间隔时间(8-18/4)(/表示每隔4小时),一个列表(1,3,5),通配符。由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?. 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午12点 "0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 * ?" 每月15日上午10:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发 有些子表达式能包含一些范围或列表 例如:子表达式(天(星期))可以为 “MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT” “*”字符代表所有可能的值 因此,“*”在子表达式(月)里表示每个月的含义,“*”在子表达式(天(星期))表示星期的每一天 “/”字符用来指定数值的增量 例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟 在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样 “?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值 当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?” “L” 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写 但是它在两个子表达式里的含义是不同的。 在天(月)子表达式中,“L”表示一个月的最后一天 在天(星期)自表达式中,“L”表示一个星期的最后一天,也就是SAT 如果在“L”前有具体的内容,它就具有其他的含义了 例如:“6L”表示这个月的倒数第6天,“FRIL”表示这个月的最一个星期五 注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题 字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * / 星期 1-7 或者 SUN-SAT , - * ? / L C # 年(可选) 留空, 1970-2099 , - * /