Spring boot学习记录

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的必须引入的依赖

  1. 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的版本号

  1. 如果是开发web项目,必须引入web支持
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 添加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

自定义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包

如下
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值