前言:学习SpringBoot不应该直接就是开始使用SpringBoot,如果直接拿来用肯定会有很多人不是很明白特别刚开始入门的,当然官网上也有快速上手的教程但是官网上跨度有点大,在这片文章中为主要是从以前没使用SpringBoot之前我们怎么做的以及慢慢的引入SpringBoot,我希望通过自己的体会和认识来帮助更多朋友来学习SpringBoot
(在这里我们先以最原始的方式来创建项目和测试)
创建一个Maven项目添加依赖和加入配置文件 application.xml
SomeBean.java
public class SomeBean {}
复制代码
application.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="someBean" class="com.jd.javaconfig.SomeBean"></bean> </beans> 复制代码
这个是基于XML配置的方式 MyTest.java
public class MyTest { @Test public void test1(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml"); SomeBean sb = ctx.getBean(SomeBean.class); System.out.println(sb); } } 复制代码
上面是我们最简单的一个Spring Demo
下面通过标签来配置Spring OtherBean.java
public class OtherBean {}
复制代码
下面我们写了一个方法返回一个SomeBean的对象我们要告诉Spring这个方法是Spring帮我们管理的bean通过@Bean标签
AppConfig .java
// 作为Spring的主配置文件 //@Configuration标签表示这个类可被Spring识别的配置对象的类,只有有这个标记的标签的类才能使用@Bean标签作用于对应的方法上面 @Configuration public class AppConfig { //@Bean标签表示让Spring帮我们管理bean @Bean public SomeBean someBean(){ return new SomeBean(); } @Bean public OtherBean otherBean(){ return new OtherBean(); } } 复制代码
不像上一个demo,这个是基于AnnotationConfigApplicationContext来配置的 MyTest.java
@Test
public void test() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
SomeBean sb = ctx.getBean(SomeBean.class);
OtherBean ob = ctx.getBean(OtherBean.class);
System.out.println(sb);
System.out.println(ob);
}
复制代码
到这里我们就已经学完了两个重要的标签 @Configuration和@Bean, @Configuration标签表示这个类可被Spring识别的配置对象的类,只有有这个标记的标签的类才能使用 @Bean标签作用于对应的方法上面 @Bean(destroyMethod = "destory", initMethod = "init")也可以通过这样的写法来配置bean的初始化方法和销毁方法
@Component
public class SomeBean {}
复制代码
@Component
public class OtherBean {}
复制代码
//@Configuration标签表示这个类可被Spring识别的配置对象的类,这有有这个标记的标签的类才能使用@Bean标签作用于对应的方法上面
// @ComponentScan:开启组件自动扫描;默认情况下,它会扫描当前类所在的包及其子包中的所有标签对象加载到Spring容器
@Configuration
@ComponentScan(basePackages="com.jd.scan")
public class AppConfig {}
复制代码
public class MyTest {
@Test
public void test() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
SomeBean sb = ctx.getBean(SomeBean.class);
OtherBean ob = ctx.getBean(OtherBean.class);
System.out.println(sb);
System.out.println(ob);
}
}
复制代码
@ComponentScan:开启组件自动扫描;默认情况下,它会扫描当前类所在的包及其子包中的所有标签对象加载到Spring容器
在someBean里依赖一个otherBean
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
@Qualifier("somebean")
private SomeBean somebean;
//@Autowired
//@Qualifier("somebean2")
//private SomeBean somebean2;
@Test
public void test() {
System.out.println(somebean.getOtherBean());
//System.out.println(somebean2.getOtherBean());
}
}
复制代码
@Configuration
public class AppConfig {
//第一种方式(对象的注入)
@Bean(destroyMethod = "destory", initMethod = "init")
public SomeBean somebean(OtherBean otherbean) {
SomeBean sBean = new SomeBean();
sBean.setOtherBean(otherbean);
return sBean;
}
//第二种方式
// @Bean
// public SomeBean somebean2() {
// SomeBean sBean = new SomeBean();
// sBean.setOtherBean(otherbean());
// return sBean;
// }
@Bean
public OtherBean otherbean() {
return new OtherBean();
}
}
复制代码
使用try来关闭容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=AppConfig.class)
public class MyTest2 {
@Test
public void test() {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) {
SomeBean sb = context.getBean(SomeBean.class, "somebean");
System.out.println(sb);
}
}
}
复制代码
public class MyDataSource {}
复制代码
public class MyRedisTemplate {}
复制代码
@Configuration
public class ConfigRedis {
@Bean
public MyRedisTemplate myRedisTemplate(){
return new MyRedisTemplate();
}
}
复制代码
@Configuration
public class ConfigDataSource {
@Bean
public MyDataSource myDatasource(){
return new MyDataSource();
}
}
复制代码
AppConfig这个类因为打上@Configuration标签所以是主配置文件,他需要连接着两个类ConfigDataSource.class,ConfigRedis.class 只需要使用@Import 标签就可以表示导入类
@Configuration
@Import({ConfigDataSource.class,ConfigRedis.class})
public class AppConfig {
}
复制代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
private MyDataSource datasource;
@Autowired
private MyRedisTemplate redisTemplate;
@Test
public void test(){
System.out.println(datasource);
System.out.println(redisTemplate);
}
}
复制代码
OtherBean.java
public class OtherBean {}
复制代码
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="otherbean" class="com.jd.importresource.OtherBean" />
</beans>
复制代码
SomeBean.java
@Setter@Getter
public class SomeBean {
private OtherBean otherBean;
public void init() {
System.out.println("===init====");
}
public void destory() {
System.out.println("====destory=====");
}
}
复制代码
AppConfig.java
@Configuration
// @importresource标签来在javaconfig中混用xml config
@ImportResource("classpath:com/jd/importresource/application.xml")
public class AppConfig {
@Bean(destroyMethod = "destory", initMethod = "init")
public SomeBean somebean(OtherBean otherbean) {
SomeBean sBean = new SomeBean();
sBean.setOtherBean(otherbean);
return sBean;
}
}
复制代码
MyTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
private SomeBean somebean;
@Test
public void test() {
System.out.println(somebean.getOtherBean());
}
}
复制代码
@ImportResource("classpath:com/jd/importresource/application.xml") 通过使用@ImportResource标签来导入资源
db.properties
db.username=username
db.password=password
db.url=url
db.driverClass=driverClass
复制代码
MyDatasource .java
@Setter@Getter@ToString@AllArgsConstructor
public class MyDatasource {
private String username;
private String password;
private String url;
private String driverClass;
}
复制代码
AppConfig .java
@Configuration
// @PropertySource代表引入外部的.properties资源文件
//@PropertySources嵌套@PropertySource引入多个外部资源文件
@PropertySource("classpath:com/jd/properties/db.properties")
public class AppConfig {
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer (){
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public MyDatasource datasource(){
return new MyDatasource(username, password, url, driverClass);
}
}
复制代码
MyTest .java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
private MyDatasource datasource;
@Test
public void test() {
System.out.println(datasource);
}
}
复制代码
@Configuration
// @PropertySource代表引入外部的.properties资源文件
//@PropertySources嵌套@PropertySource引入多个外部资源文件
@PropertySource("classpath:com/jd/properties/db.properties")
public class AppConfig {
//Environment代表spring的环境,在环境里面只有两种东西: 1,读入的外部资源文件(properties); 2,profile
@Autowired
private Environment env;
@Bean
public MyDatasource datasource() {
return new MyDatasource(env.getProperty("db.username"), env.getProperty("db.password"),
env.getProperty("db.url"), env.getProperty("db.driverClass"));
}
}
复制代码
db-dev.properties
db-profile.properties
db.username=username
db.password=password
db.url=url
db.driverClass=driverClass
复制代码
MyDatasource.java
@Setter@Getter@ToString@AllArgsConstructor
public class MyDatasource {
private String username;
private String password;
private String url;
private String driverClass;
}
复制代码
//生产环境的配置对象
@Configuration
@Profile("pro")
@PropertySource("classpath:com/jd/profile/db-pro.properties")
public class ConfigPro {
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;
@Bean
public MyDatasource datasource() {
return new MyDatasource(username, password, url, driverClass);
}
}
复制代码
//针对开发环境的配置
@Configuration
@Profile("dev")
@PropertySource("classpath:com/jd/profile/db-dev.properties")
public class ConfigDev {
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;
@Bean
public MyDatasource datasource() {
return new MyDatasource(username, password, url, driverClass);
}
}
复制代码
AppConfig .java
@Configuration
@Import({ ConfigDev.class, ConfigPro.class })
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
复制代码
MyTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
@ActiveProfiles("dev")
public class MyTest {
@Autowired
private MyDatasource datasource;
@Test
public void test() {
System.out.println(datasource);
}
}
复制代码
先演示在地址栏访问loclhost:8080/hello返回字符串hello world #####1.在pom.xml文件中加入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
复制代码
HelloSpringBoot.java
@SpringBootApplication
@Controller
public class HelloSpringBoot {
@RequestMapping("hello")
@ResponseBody
public String hello() {
return "hello world";
}
public static void main(String[] args) {
SpringApplication.run(HelloSpringBoot.class, args);
}
}
复制代码
' __ _ ( ) __ __ _ / / /
( ( )_
_ | '_ | ' | | ' /` | / / /
// )| | )| | | | | || ( | | ) ) ) ) ' |
| .__| | | | | | _ , | / / / / =========| |==============| /=/ / / / :: Spring Boot :: (v1.5.6.RELEASE)分析:1,继承spring-boot-starter-parent,引入基本的依赖管理配置; 2,引入spring-boot-starter-web,自动引入了springweb相关的包; 3,@SpringBootApplication:这个注解告诉springboot自动的去完成相关配置,包括基础类的加载,bean的扫描等等,这个后面详细介绍;简单理解为这个标签为我们的应用配置完成了很多基本功能; 4,SpringApplication.run:这个是springboot为我们提供的最大的区别,在于springboot不再是一个web应用,需要我们自己去打包,部署,启动tomcat,springboot默认把tomcat打包到应用中,我们可以以正常的运行jar的方式来运行springboot应用;
应用独立运行: 1,pom文件中添加:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
复制代码
2,使用package命令打包,在命令行中使用java -jar xx.jar运行;注意,一定要引入spring-boot-maven-plugin之后运行package打包才能正常运行;
3,直接使用maven插件:spring-boot:run运行;
Springboot的优缺点1. 创建独立的Spring应用程序 2. 嵌入的Tomcat,无需部署WAR文件 3. 简化Maven配置 4. 自动配置Spring 5. 提供生产就绪型功能,如日志,健康检查和外部配置 6. XML没有要求配置 7. 非常容易和第三方框架集成起来; 缺点: 1,版本更新较快,可能出现较大变化; 2,因为约定大于配置,所以经常会出现一些很难解决的问题;
1,Springboot应用的基本结构:通过start.spring.io(网址)创建一个springboot应用: 2,spring-boot-starter-parent简介: 1,包含了常用版本属性; 要修改java编译版本,可以修改: <java.version>1.7</java.version> 2,包含了常用的dependenceManagement; 3,Springboot非常优秀的地方在于提供了非常多以spring-boot-starter- 开头的开箱即用的工具包,常见工具包有以下一些: spring-boot-starter:核心的工具包,提供了自动配置的支持,日志和YAML配置支持; spring-boot-starter-activemq:针对快速集成ActiveMQ的工具包; spring-boot-starter-aop:提供了快速集成SpringAOP和AspectJ的工具包; spring-boot-starter-data-redis:提供了快速集成Redis和Jedis的工具包; spring-boot-starter-freemarker:提供了快速集成Freemarker的工具包; spring-boot-starter-mail:提供了快速集成邮件发送的工具包; spring-boot-starter-test:提供了对Springboot应用的测试工具包; spring-boot-starter-web:提供了对web开发的工具包,包括基于SpringMVC的RESTful应用开发,内置的tomcat服务器等; spring-boot-starter-actuator:提供了对生产环境中应用监控的工具包; spring-boot-starter-logging:提供了对日志的工具包,默认使用Logback; 3,Springboot应用的热部署: 除了使用JRebel来实现热部署,还可以使用Springboot提供的spring-boot-devtools包来完成Springboot应用热部署; org.springframework.boot spring-boot-devtools true 1)原理: SpringBoot重启是reload重启,通过监控classpath的变化,如果classpath中的文件发生变化,即触发重启。springboot通过两个classpath来完成reload,一个basic classloader中加载不变的类,一个restart classloader中加载classpath中的类,重启的时候,restart classloader中的类丢弃并重新加载; 2)排除资源: spring.devtools.restart.exclude=static/ ,templates/ spring.devtools.restart.additional-exclude=public/ * (处理默认配置排除之外的) spring.devtools.restart.enabled=false (禁用自动重启)
@SpringBootApplication简介: @SpringBootApplication由三个主要的标签构成:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan 1)@SpringBootConfiguration:本质就是一个@Configuration,代表这是spring容器的主配置类; 2)@EnableAutoConfiguration:开启自动配置,Springboot使用这个标签自动的把内置的符合条件的@Configuration类加载进入应用; 可以查看spring-boot-autoconfigure包中的META-INF/spring.factories文件中的配置项(原理,由@EnableAutoConfiguration标签引入的AutoConfigurationImportSelector类中,使用Spring的SpringFactoriesLoader类实现加载) 3)@ComponentScan:自动扫描;
SpringApplication简介: 1,SpringApplication类提供了一个标准化的应用执行流程,并在这个执行流程中为我们提供了一些应用扩展点;但大部分情况下,我们只需要使用它就可以了; 2,SpringBoot提供了一些扩展点,比如修改Banner: 1)创建一个banner.txt 2)设置banner,在配置文件中使用spring.main.banner-mode=off 3,可以通过创建对象的方式来运行SpringApplication
2)通过builder完成:
复制代码
4,参数的处理:在应用启动过程中,可以通过启动参数给应用传递一些额外的参数来控制应用的运行; 1,在main方法中可以直接使用传入的参数; 2,可以任何类中直接通过@Autowired注入一个ApplicationArguments对象;
为什么要用日志? 1.比起System.out.println,日志框架可以把日志的输出和代码分离; 2.日志框架可以方便的定义日志的输出环境,控制台,文件,数据库; 3.日志框架可以方便的定义日志的输出格式和输出级别;
Springboot的默认日志使用: 1.Springboot默认已经开启日志;默认的日志格式为:时间 日志级别 PID 线程名称 日志类 日志说明 2.Springboot的日志区别系统日志和应用日志; 3.Springboot推荐使用Logback作为日志框架(common-logging,java-logging,log4j,logback,slf4j)
Logback使用方法(推荐使用logback自己的配置文件) 1.springboot默认支持logback.xml或者logback-spring.xml,推荐使用logback-spring.xml,springboot会增加额外功能; 2.可以通过logging.config=classpath:mylogback.xml指定自己的logback配置文件(不推荐); 3.一个典型的logback配置文件:
Logback使用介绍: 1,:Logback配置根元素 属性包括: 1,scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 2,scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 3,debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 子元素: :上下文名字; :定义属性,可以使用${}在配置文件中使用;
2,:在logback中是用于具体记录日志的组件,可以用来配置日志记录方式,日志记录格式等; 属性包括: name:appender的名字,用于下面在配置日志的时候指定; class:使用到的appender类;
常见的appender: 1,ch.qos.logback.core.ConsoleAppender:输出到控制台; 2,ch.qos.logback.core.FileAppender:输出到文件; 3,ch.qos.logback.core.rolling.RollingFileAppender:输出到文件,可以配置滚动策略,当日志达到某个条件之后分文件记录; 4,还有其他的appender,比如写到数据库等;
元素的基本格式:
元素用来规定日志的输出格式,所有表达式都以%开始表示接下来是一个特殊标识符 常见标识符: 1,%logger{n}:输出Logger对象类名,n代表长度; 2,%class{n}:输出所在类名, 3,d{pattern}或者date{pattern}:输出日志日期,格式同java; 4,L/line:日志所在行号; 5,m/msg:日志内容; 6,method:所在方法名称; 7,p/level:日志级别; 8,thread:所在线程名称;
常见的appender使用: 1)ConsoleAppender输出到控制台,子元素: :日志格式化 :System.out(默认)或者System.err
2)FileAppender输出到文件,子元素: file:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。 append:文件结尾,如果是 false,清空现存文件,默认是true。 encoder:对日志进行格式化
3)RollingFileAppender输出到文件,可以设置文件滚动(分割)条件,子元素: append:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。 rollingPolicy:滚动策略,涉及文件移动和重命名。 常用滚动策略: ch.qos.logback.core.rolling.TimeBasedRollingPolicy:按照时间控制来控制记录文件; fileNamePattern:文件名称格式,以%d{pattern}; maxHistory: 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。(以文件最小时间为准)
SizeAndTimeBasedRollingPolicy:按照时间和大小控制记录文件; fileNamePattern:文件名称格式,可以使用%i来控制索引编号; maxFileSize:这是活动文件的大小,默认值是10MB maxHistory: 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。(以文件最小时间为准)
下面我们来通过一个小Demo来说明 application.properties
db.username=username
db.password=password
db.url=url
springboot.randomlong=${random.long[1,100]}
复制代码
MyDatasource.java
@Setter@Getter
public class MyDatasource {
private String username;
private String password;
private String url;
}
复制代码
HelloController.java
@Controller
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@Autowired
private MyDatasource datasource;
@RequestMapping("hello")
@ResponseBody
public String hello() {
//error<warn<info<debug<trace
logger.info("转出成功");
if (logger.isDebugEnabled()) {
logger.debug("准备转出10000");
}
if (logger.isTraceEnabled()) {
logger.trace("连接数据库");
logger.trace("查询账户余额为12000");
}
if (logger.isDebugEnabled()) {
logger.debug("检查转出账户...");
logger.debug("转出检查成功");
logger.debug("执行转出10000");
logger.debug("转出成功");
}
logger.info("转入成功");
System.out.println(datasource);
return "hello world";
}
}
复制代码
App.java
@SpringBootApplication
public class App {
@Bean
@ConfigurationProperties(prefix = "db")
public MyDatasource datasource() {
return new MyDatasource();
}
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).bannerMode(Mode.OFF).build().run(args);
}
复制代码
}
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
<target>System.out</target>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
<file>springbootdemo.log</file>
<append>true</append>
</appender>
<appender name="ROLLFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>springboot.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="SIZEROLLFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>springboot.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
<appender-ref ref="SIZEROLLFILE" />
</root>
</configuration>
复制代码
添加依赖 引入spring-boot-starter-freemarker;
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
复制代码
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>freemarker</display-name>
<!-- SpringMVC前端控制器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.do</welcome-file>
</welcome-file-list>
</web-app>
复制代码
application.xml
<!--开启注解扫描 -->
<context:component-scan base-package="com.jd" />
复制代码
application-web.xml
<import resource="classpath:application.xml" />
<!-- 支持springmvc的注解驱动 -->
<mvc:annotation-driven />
<!-- 配置一个freemarker的配置对象 -->
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 配置freemarker的文件编码 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- 配置freemarker寻找模板的路径 -->
<property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>
<!-- 配置一个针对于freemarker的viewresovler -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!-- 配置逻辑视图自动添加的后缀名 -->
<property name="suffix" value=".ftl" />
<!-- 配置视图的输出HTML的contentType -->
<property name="contentType" value="text/html;charset=UTF-8" />
</bean>
复制代码
FreemarkerController.java
@Controller
public class FreemarkerController {
@RequestMapping("hello")
public String hello(Model model){
model.addAttribute("msg","hello 我是 freemarker");
return "hello";
}
}
复制代码
添加依赖
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
复制代码
创建模板
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${msg}</h1>
</body>
</html>
复制代码
FreemarkerController.java
@Controller
public class FreemarkerController {
@RequestMapping("hello")
public String hello(Model model){
model.addAttribute("msg","hello 我是 freemarker");
return "hello";
}
}
复制代码
App.java
//运行main
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
复制代码
访问网页
Springboot对freemarker的配置:1,spring.freemarker.enabled=true:是否开启freemarker支持; 2,spring.freemarker.allow-request-override:是否允许request中的属性覆盖model中同名属性;默认false; 3,spring.freemarker.allow-session-override:是否允许session中的属性覆盖model中同名属性;默认false; 4,spring.freemarker.cache:是否支持模板缓存;默认false; 5,spring.freemarker.charset=UTF-8:模板编码 6,spring.freemarker.content-type=text/html:模板contenttype; 7,spring.freemarker.expose-request-attributes:是否开启request属性expose,默认false; 8,spring.freemarker.expose-session-attributes:是否开启session属性expose,默认false; 9,spring.freemarker.expose-spring-macro-helpers:是否开启spring的freemarker宏支持;默认为false; 10,spring.freemarker.prefer-file-system-access:默认为true,支持实时检查模板修改; 11,spring.freemarker.prefix:加载模板时候的前缀; 12,spring.freemarker.settings.*:直接配置freemarker参数 13,spring.freemarker.suffix:模板文件后缀; 14,spring.freemarker.template-loader-path=classpath:/templates/:模板加载地址
application.properties
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html;charset=UTF-8
spring.freemarker.expose-session-attributes=true
复制代码
GlobalExceptionHandler.java
@ControllerAdvice
public class GlobalExceptionHandler {
//@ExceptionHandler(logicException.class)也可以分情况处理异常
@ExceptionHandler(Exception.class)
public String errorHandler(Model model, Exception e) {
model.addAttribute("error", e.getMessage());
//到模板找到err.ftl将错误信息显示出来
return "err";
}
}
复制代码
2)统一的异常页面 1,SpringBoot默认情况下,把所有错误都重新定位到/error这个处理路径上,由BasicErrorController类完成处理; 2,SpringBoot提供了默认的替换错误页面的路径: 1,静态错误页面默认结构:(按照这个目录结构放置错误页面报错时就会自动找到相应的界面) src/ resources/public/error/404.html src/ resources/public/error/ 403.html src/ resources/public/error/ 5xx.html
2,也可以使用模板页面: src/resources/templates/error/5xx.ftl 该路径方式是通过ErrorMvcAutoConfiguration中的DefaultErrorViewResolver完成的;
集成DataSource方式1:先加入依赖
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
复制代码
DatasourceController .java
@Controller
public class DatasourceController {
@Autowired
private DataSource dataSource;
@RequestMapping("ds")
@ResponseBody
public String datasource() {
return dataSource.getClass() + " " + dataSource.toString();
}
}
复制代码
运行main
@SpringBootApplication
public class App {
//使用代码的方式实现datasource
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql:///p2p");
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setInitialSize(5);
dataSource.setMinIdle(5);
return dataSource;
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
复制代码
使用配置文件的方式 application.properties
ds.username=root
ds.password=123456
ds.url=jdbc:mysql:///p2p
ds.driverClassName=com.mysql.jdbc.Driver
ds.initialSize=3
复制代码
App.java
@Bean
@ConfigurationProperties(prefix = "ds")
public DataSource dataSource(Properties properties) throws Exception {
return DruidDataSourceFactory.createDataSource(properties);
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
复制代码
集成DataSource方式3:修改配置文件
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql:///p2p
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.initialSize=3
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
复制代码
mybatis集成: 使用mybatis-spring-boot-starter来完成mybatis集成;
1,引入依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
复制代码
2,正常完成mapper接口和mapper.xml 3,mybatis-spring-boot-starter提供了以下配置(具体参考MyBatisProperties对象):
mybatis.configLocation:mybatis的配置文件地址; mybatis.mapperLocations:映射文件地址; mybatis.typeAliasesPackage:别名扫描包;
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql:///p2p
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.initialSize=3
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.mapperLocation=classpath:com/jd/springboot/mybatis3/*Mapper.xml
mybatis.typeAliasesPackage=com.jd.springboot.mybatis3
复制代码
4,使用@MapperScan标签扫描mapper接口
@SpringBootApplication
@MapperScan(basePackages="com.jd.springboot.mybatis3")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
复制代码
1,直接开启@EnableTransactionManagement注解;相当于在xml中配置 tx:annotation-driven/
@SpringBootApplication
@MapperScan(basePackages="com.jd.springboot.demo.mybatis1.mapper")
@EnableTransactionManagement
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
复制代码
如果在classpath中添加的是spring-boot-starter-jdbc,那么springboot自动创建DataSourceTranscationManager;
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
复制代码
将事务相关配置抽取到XML中,使用importResource引入
1,引入aop
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
复制代码
2,application-tx.xml
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="list*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.jd.springboot.demo..service.*Service.*(..))"
id="pointCut" />
<aop:advisor advice-ref="advice" pointcut-ref="pointCut" />
</aop:config>
复制代码
3,引入配置
@SpringBootApplication
@MapperScan(basePackages = "com.jd.springboot.demo.mybatis1.mapper")
@ImportResource(locations="classpath:application-tx.xml")
public class App {}
复制代码
1,仍然使用MultipartFile完成上传,Springboot是使用Servlet3中的Part对象完成上传,不是使用的fileupload;
2,上传相关配置: spring.http.multipart.enabled=true:是否允许处理上传;
spring.http.multipart.maxFileSize=1MB:允许最大的单文件上传大小,单位可以是kb,mb;
spring.http.multipart.maxRequestSize=10MB:允许的最大请求大小;
3,也可以通过创建一个MultipartConfigElement类型的bean对上传进行配置:
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory mcf = new MultipartConfigFactory();
mcf.setMaxFileSize("1MB");
mcf.setMaxRequestSize("10MB");
return mcf.createMultipartConfig();
}
复制代码
4,关于上传文件的处理: 因为应用是打成jar包,所以一般会把上传的文件放到其他位置,并通过设置 spring.resources.static-locations 来完成资源位置映射。
spring.resources.static-locations=classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/, file:/Users/zhangshuai/devs/workspace/springboot-demo/upload/
#####SpringBoot总结 1.Maven中项目的继承依赖包的管理 第1:在父项目中添加dependency,子项目不需要添加 第2:在父项目中添加dependencyManagement标签,然后在添加dependency,子类对应的添加需要的dependency,但不需要写版本号 2.项目分为前台和后台两个应用的好处 从安全性考虑,后台是给公司管理人员用的,前台是给用户用的,访问的URL地址是不一样的,那这样的话前台用户就不可能通过各种尝试去访问后台管理系统了。 从性能方面考虑,项目分成前台和后台把请求分发到不同的服务器中,降低单个服务器的压力。 3.什么是乐观锁?乐观锁能解决什么问题? 乐观锁(Optimistic Lock): 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 sql 上的体现:加版本/时间戳控制语句 update set version = version+1 ... from .... where version = xxx 解决的问题:数据并发问题(丢失更新/脏读)
4.事务是什么?事务有哪些特性?事务用来干什么? (1)在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。 特性:
为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
5.Springboot应用的启动原理? Springboot应用可以在一个主启动类中运行main方法或者打成jar包直接运行该jar包。 因为Springboot应用一定会在主启动类贴上一个@SpringBootApplication注解,该注解有包含很多配置,相当于spring的主配置文件,并且springboot应用内嵌web服务器,在我们启动应用时,会先根据@SpringBootApplication注解的配置初始化spring容器,并运行在内嵌的web服务器上。
6.@Configuration标签,@ComponentScan和@Bean标签各自的作用; @Configuration:贴上该注解的类会被spring当成配置对象解析,可以在该配置对象创建bean注入到spring容器(相当于之前我们application.xml写的配置) @ComponentScan:该注解与@Configuration:结合一起使用,可以扫描应用中的组件,比如贴了@Controller,@Service,@Component的类,并注入到spring容器中。此外,改注解可以填写扫描的包路径,如果不写的话就默认扫描贴了该注解的类所在的包及其子包。 @Bean:该注解结合@Configuration一起使用,作用是把贴上该注解的方法返回的类注入到spring容器中。 7.@ConfigurationProperties标签的作用; 该注解起到参数绑定的作用,可以非常方便的把配置文件的配置信息绑定到Properties对象上,并且可以控制到具体哪些前缀的配置信息需要绑定 8.日志级别: error>warn>Info>debug>trace