您的位置:首页 > 编程语言 > Java开发

Spring boot学习记录

2017-11-27 08:48 441 查看
Spring具有繁琐的xml配置,目前Spring从3.x过渡到4.x的版本,推荐使用Java配置取代xml配置。Spring boot并不是什么新的技术或功能,只是为Spring框架整合许多第三方的技术。

1.Spring的Java配置方式

1.1基本注解@Configuration和@Bean

java配置方式主要通过@Configuration和@Bean这两个注解来实现的。

1. @Configuration 作用于类上,相当于一个xml配置文件

2. @Bean作用于方法上,相当于xml中的<bean>标签

下面Java配置具体代码的实现,和之前xml配置不同就是多了这个文件,省去了xml的配置,其他的实体类、服务层、Controller都一样的写法

package cn.itcast.springboot.javaconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
*
* @author Weiguo Liu
* @data 2017年11月27日
*/

//这个注解,表明该类是一个Spring的配置,相当于一个xml文件
@Configuration

//配置扫描包,即Spring管理的文件包路径
@ComponentScan(basePackages = "cn.itcast.springboot.javaconfig")
public class SpringConfig {

@Bean// 通过该注解来表明是一个Bean对象,相当于xml中的<bean>标签,这里提供一个获取Dao的方法即可
public UserDAO getUserDAO() {
return new UserDAO(); // 直接new对象做演示
}

}


1.2 读取外部资源配置文件

以前通过xml配置是通过context:property-placeholder这个标签来配置文件地址,辅助${xx}这样方式获取具体的配置属性,在Java注解配置,用一个SpringConfiguration.java文件代替了xml,所以外部文件的引入也是在这个配置文件上做文章,外部资源文件的引入直接在Configuration类上加上

@PropertySource(value={"classpath:xxx"})


即可引入(xxx表示配置文件名,通常是”xxx.properties”的形式),然后在配置文件中配置具体属性的时候,直接在该属性上用@Value注解注入即可,和xml中的表示一样:比如

@Value("${jdbc.url}")


当然如果需要引入多个外部文件就应该写成

@PropertySource(value={"classpath:xxx","classpath:外部文件2"})


这里因为可能引入的外部文件不存在,所以通常会配置一个忽略不存在的外部文件的设置

@PropertySource(value = { "classpath:jdbc.properties" }, ignoreResourceNotFound = true)


下面是具体的典型综合配置代码

配置文件jdbc.properties还像之前那么写即可

package cn.itcast.springboot.javaconfig;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.jolbox.bonecp.BoneCPDataSource;

/**
*
* @author Weiguo Liu
* @data 2017年11月27日
*/

//这个注解,表明该类是一个Spring的配置,相当于一个xml文件
@Configuration

//配置扫描包,即Spring管理的文件包路径
@ComponentScan(basePackages = "cn.itcast.springboot.javaconfig")

//引入外部配置文件,忽略不存在的文件
@PropertySource(value = { "classpath:jdbc.properties" }, ignoreResourceNotFound = true)
public class SpringConfig {

@Bean// 通过该注解来表明是一个Bean对象,相当于xml中的<bean>
public UserDAO getUserDAO() {
return new UserDAO(); // 直接new对象做演示
}

//获取配置文件中的一些具体的属性
@Value("${jdbc.username}")
private String userName;

@Value("${jdbc.password}")
private String password;

@Value("${jdbc.url}")
private String jdbcUrl;

@Value("${jdbc.driverClass}")
private String driverClass;

//destroyMethod="close"的作用当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
@Bean(destroyMethod="close")
//这里使用的连接池不同,所以获取的对象会有所不同,通常会写成getBoneCPDataSource
//但是Spring中会默认使用方法名作为bean的id,使用getxx不太适合,故改成boneCPDataSource
public BoneCPDataSource boneCPDataSource() {
BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
boneCPDataSource.setUsername(userName);
boneCPDataSource.setPassword(password);
boneCPDataSource.setJdbcUrl(jdbcUrl);
boneCPDataSource.setDriverClass(driverClass);

// 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0
boneCPDataSource.setIdleConnectionTestPeriodInMinutes(60);
// 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0
boneCPDataSource.setIdleMaxAgeInMinutes(30);
// 每个分区最大的连接数
boneCPDataSource.setMaxConnectionsPerPartition(100);
// 每个分区最小的连接数
boneCPDataSource.setMinConnectionsPerPartition(5);

return boneCPDataSource;
}

}


2.Spring Boot

以上基于Java注解的叨叨就是为了Spring Boot的引入,它里面基本都是注解。

静态语言:先编译,再运行

动态语言:不需要编译,直接运行

Java是属于静态语言

JS属于动态语言

spring boot可以快速运行项目,之所以运行快速是因为实际上实在运行的一个jar,而不是一个工程,所以spring boot适用于开发测试(独立运行的jar,内嵌SERVLET容器(实际就是Tomcat)不需要再将它部署到Tomcat中),不太适合实际运用,但是还是可以将整个项目作为一个war包发布到生产环境中去。总而言之,在开发测试阶段运行的就是一个独立的jar包,但是在开发完之后打包成war包,丢到生产环境中,他又是一个完整的项目,非常方便,使用Spring boot可以极少使用或者不用Spring的配置(很多都已经内置了)。

2.1 Spring boot的必须引入的依赖

spring项目必须将parent设为spring boot

它包含了大量的默认配置,大大简化了我们的开发

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


注意在其后引入的一些spring的一些模块时,不需要再写版本号version,因为这个里面已经包含了整个spring的版本号

如果是开发web项目,必须引入web支持

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


添加spring boot的插件(可省)

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>


2.2 简单的Spring boot应用

1.xxxApplication

一般情况下,Springboot项目都会有一个叫做xxxApplication的类,这个类就是整个项目的入口,如下:

package cn.itcast.springboot.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication//表明是一个Springboot的应用
@Controller//表明是SpringMVC的类Contrller
@Configuration//表明自身就是一个配置文件
public class HelloApplication {

@RequestMapping("hello")
@ResponseBody//有这个注解就会使用消息转化器输出返回的字符串
public String hello() {
return "hello world!";
}

public static void main(String[] args) {
//SpringApplication.run()方法中传入的类必须要有@SpringBootApplication注解,然后运行这个类
//这个类其实就是Spring Boot的入口方法
SpringApplication.run(HelloApplication.class, args);
}

}


【注意】

1. @SpringBootApplication是Spring Boot项目的核心注解,主要作用是开启自启动配置,是组合注解,里面也配置了自动扫描该App同级目录以及子目录下的所有类,如果不想让它自动配置哪个,后面可以接(execlude={xxx.class}),即可对xxx这个类不进行自动配置

2. @Configuration是设置Spring的配置类,通常spring boot项目中推荐使用@SpringBootConfiguration代替它(它的底层包含了@Configuration这个注解)

3. @Controller表示该类是一个SpringMVC的Controller控制器

4. main方法是启动一个应用,就是Spring boot应用的入口

2. spring boot项目的启动

spring boot项目中有两种启动方式,一种是直接运行xxxApplication(run As Java Application)获取右击项目RunAs–>Spring boot App;另一种是采用Maven插件的方式运行,刚刚2.1中第3部配置spring boot maven的插件就提供了这个作用,步骤如下:

右击项目–>Run As–>Run Configurations–>Maven Build–>右击new,出现如下窗口



Name随意填写,Base directory选择项目所在位置即可,Goals填入maven的启动命令:spring-boot:run即可,最后点击run便可运行。

3.启动日志

启动这个类的时候控制台会输出如下的一些信息

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )  //这个是spring boot的logo,其实上是个banner,默认是这个,当然可以随意改
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::        (v1.5.2.RELEASE) //Spring Boot的版本号

2017-11-27 12:51:54.247  INFO 13288 --- [           main] c.i.springboot.demo.HelloApplication     : Starting HelloApplication on Mr-Lius-Computer with PID 13288 (F:\MyWork\GitHub\LocalGitRepository-Eclipse\itcast-springboot\target\classes started by Weiguo Liu in F:\MyWork\GitHub\LocalGitRepository-Eclipse\itcast-springboot)
2017-11-27 12:51:54.251  INFO 13288 --- [           main] c.i.springboot.demo.HelloApplication     : No active profile set, falling back to default profiles: default
2017-11-27 12:51:54.748  INFO 13288 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@62db0cfc: startup date [Mon Nov 27 12:51:54 CST 2017]; root of context hierarchy
2017-11-27 12:51:57.868  INFO 13288 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)  //监听8080端口
2017-11-27 12:51:57.890  INFO 13288 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2017-11-27 12:51:57.892  INFO 13288 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.11 //内核是Tomcat,就是前面说的springboot是内嵌了Tomcat
2017-11-27 12:51:58.125  INFO 13288 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-11-27 12:51:58.125  INFO 13288 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3381 ms
2017-11-27 12:51:58.377  INFO 13288 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/] //初始化SpringMVC的dispatcherServlet为“/”,即web项目默认是无项目名,直接访问映射即可,所以上述的应用只需要访问http://localhost:8080/hello即可输出
2017-11-27 12:51:58.383  INFO 13288 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-11-27 12:51:58.383  INFO 13288 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-11-27 12:51:58.383  INFO 13288 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-11-27 12:51:58.383  INFO 13288 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2017-11-27 12:51:58.891  INFO 13288 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@62db0cfc: startup date [Mon Nov 27 12:51:54 CST 2017]; root of context hierarchy
2017-11-27 12:51:58.988  INFO 13288 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello]}" onto public java.lang.String cn.itcast.springboot.demo.HelloApplication.hello()
2017-11-27 12:51:58.996  INFO 13288 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-11-27 12:51:58.997  INFO 13288 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-11-27 12:51:59.076  INFO 13288 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-11-27 12:51:59.076  INFO 13288 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-11-27 12:51:59.142  INFO 13288 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-11-27 12:51:59.571  INFO 13288 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-11-27 12:51:59.740  INFO 13288 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-11-27 12:51:59.748  INFO 13288 --- [           main] c.i.springboot.demo.HelloApplication     : Started HelloApplication in 8.239 seconds (JVM running for 9.403)
2017-11-27 12:53:59.515  INFO 13288 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-11-27 12:53:59.515  INFO 13288 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-11-27 12:53:59.535  INFO 13288 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 20 ms


4.自定义Banner

第三部启动日志中已经提供对部分做了说明,Spring Boot项目默认的Banner是一个Spring的标志,自己可以百度Banner生成器(比如:http://www.network-science.de/ascii/),输入你想做的Banner字符,然后复制下来保存到本地(比如保存到本地的banner.txt文件),然后将banner.txt文件文件复制到resources目录(即项目中的src/main/resources目录)中即可,下次启动项目的时候会自动加载,比如修改成我姓名的拼音然后按照上述流程启动将会出现下面的Banner



当然也可以关闭这玩意儿,在xxxApplication中的main方法修改成下面的即可

SpringApplication app = new SpringApplication(HelloApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);


2.3 Spring Boot的全局配置文件

spring boot项目可以使用一个全局的配置文件指定默认的配置,而且它的名字只能叫做application.properties或者application.yml(推荐使用,较为方便),放到resources目录下。比如:

# 1.application.properties配置,修改Tomcat的端口和映射路径(即此时访问hello的地址就不是上述的localhost:8080/hello而是localhost:8088/hello.html)

server.port=8088
server.servlet-path=*.html


如果使用yml语言配置就是

注意冒号后面一定要加空格

server:
port: 8088
servlet-path: "*.html"  #这里配置加了双引号不然报错


当然还有详细的配置选项见https://github.com/Jacksonary/CodeRepository/blob/master/spring-boot-configurationfile.pl

2.4自定springboot的一些默认配置

2.4.1 自定义静态资源位置

# 在全局配置文件中可以指定静态资源的位置spring.resources.static-locations
spring.resources.static-locations=classpath:/public/,classpath:路径2


如果不配置静态文件路径(默认为/)或者进入路径为*.xxx的,那么将静态资源直接放到webapp目录下即可访问

2.4.1自定义消息转换器

这个消息转化器编码是Controller中的return的字符编码问题,不是指jsp页面中的编码

如果页面中文乱码,可以在xxxApplication中加入自定义的消息转换器,默认是UTF-8

自定义消息转化器,只需要在@Configuration的类中添加消息转化器的@Bean到Spring的容器中,就会被Springboot自动加载到容器中

//自动加入SpringMVC的消息转换器中(取代springboot默认的消息转换器),访问页面上如果出现中文乱码,可以把这个代码片加进去
@Bean
public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
return converter;
}


2.4.2自定SpringMVC配置

比如加一个拦截器,这时必须通过继承WebMvcConfigurerAdapter才行,而且这个类必须和xxxApplication类处在同级目录或者其所在目录的子目录下面才能被扫描。下面是简单的实现代码

package cn.itcast.springboot.demo;

import java.nio.charset.Charset;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration //申明这是一个配置
public class MySpringMVCConfig extends WebMvcConfigurerAdapter{

// 自定义拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
HandlerInterceptor handlerInterceptor = new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("自定义拦截器............");
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
}
};
//其中/**表示所有的请求都会经过这个自定的拦截器
registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
}

// 自定义消息转化器的第二种方法
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter converter  = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converters.add(converter);
}

}


3.Spring Boot项目中JSP页面无法访问的问题

由于Spring Boot中是内嵌Tomcat的,但是注意这个Tomcat是不支持jsp页面的,必须导入相应的依赖才能访问。

<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>


4.发布Spring Boot项目到独立的Tomcat中(即实际生产环境中)

1.工程打包方式为war

这一点可以在创建Spring Starter Project时指定packaging类型为war而不是jar

2.设置spring-boot-starter-tomcat依赖的作用域

将spring-boot-starter-tomcat的作用域设置为provided,表示在工程打包时会自动排除这个依赖,使用生产环境中Tomcat而不是使用SpringBoot中内嵌的Tomcat,没有一定要加上(很多情况因为传递依赖并没有显式的表现出来)

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>


3.修改代码,设置启动配置

让启动类继承SpringBootServletInitializer,重写其中的configure()方法,将Spring Boot的入口类设置进去。如下代码片

public class HelloApplication extends SpringBootServletInitializer {
......

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//设置启动类,用于独立Tomcat的运行入口
return builder.sources(HelloApplication.class);
}

......

}


4.打包工程

1.打包成war包

右击项目–>Run As–>Run Configurations–>在Goals中输入命令:clean package,勾选Skip Tests–>Run即可。



这样即可打包war包,丢到Tomcat中的webapp目录下即可,运行访问会自动解压,即使没有web.xml文件,但是Spring Boot项目在第三步继承了SpringBootServletInitializer类在打包的时候会自动写一些启动类,所以不必再写web.xml文件

2.打包成jar包

因为上述建工程的时候直接选了packaging为war,所以不需要动,如果要打包成jar包,在pom.xml需要进行修改,将packaging标签改成jar

<packaging>jar</packaging>


然后执行打包命令:Run As–>Maven install即可,打包好的jar包就在项目target目录下面。运行的时候,在dos窗口下,切换到jar包所在目录,执行以下命令即可运行jar包

java -jar jar包


如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  springboot