Hello World 构建完整的RESTful Web服务

http://localhost:8080/greeting 这样的一个请求被认为是Restful请求,如果能得到正确结果,认为是一个Restful服务。收到请求后服务器会返回相应的json参数,json参数被解析成网页上的数据。当然,不同的Restful请求会返回不同的数据,我们可以在url上选择使用不同的参数。

从服务的角度来看整个过程,首先需要一个实体类来表示json格式

创建资源表示类

即为json格式的数据建模,例如对

{
    "id": 1,
    "content": "Hello, World!"
}

我们需要建一个java类,当然类里面除了表示id和content的数据字段,还需要有构造函数和访问器(即get、set)。那么这个类是怎么和json格式的数据关联起来的呢?Spring中使用Jackson Json库自动将类型实例Greeting封装到Json中。

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

创建资源控制器

建模建好了,需要控制这个数据类型了。那些不同的Http Restful 请求是怎么被识别,做出不同操作,返回不同数据类型的?靠的就是资源控制器 resource controller。
构建一个资源控制器,一般通过@RestController注释来识别,即一个类加上相应的注解就变成了资源控制器。资源控制器通过返回类的新实例来处理各种不同的Restful请求,比如请求一个get,那么返回一个资源表示类的新实例;而资源表示类会被解析成json,这在上面已经讨论了。
来看这个资源控制器

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}

1.@RestController 表示这是一个资源控制器,用来处理Http请求。@RestController 中每个方法都返回一个域对象而不是视图。它是速记@Controller和@ResponseBody拼凑在一起的。
2.@RequestMapping 注释表示其括号后的url请求(/greeting)会映射到其注释下的这个方法。即指定每个Restful请求会对应什么操作。 上面的示例未指定GETvs. PUT,POST等等,因为@RequestMapping默认情况下映射所有HTTP操作。使用@RequestMapping(method=GET)缩小这种映射。
3.@RequestParam 讲查询字符串的值绑定name到greeting方法的name参数中,即取出url中的name当做方法的参数。
4.传统MVC控制器和上面的RESTful Web服务控制器之间的关键区别在于创建HTTP响应主体的方式。这个RESTful Web服务控制器只是填充并返回一个对象,而不是依靠视图技术(即不会直接改html)来执行问候数据的服务器端呈现Greeting。对象数据将作为JSON直接写入HTTP响应。

使应用程序可执行

1.打包war包,部署到外部服务器。
2.打包成jar包,由 java main()方法启动。在此过程中,您使用Spring的支持将Tomcat servlet容器嵌入为HTTP运行时,而不是部署到外部实例。
来看这个启动类

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

1.首先我们看到了由于加了@SpringBootApplication注释,这个类变成了一个启动类。并且这个注释包含了很多内容,如下的都是自动包含在@SpringBootApplication中了
2.@Configuration 标记该类作为应用程序上下文的bean定义的来源。
3.@EnableAutoConfiguration 告诉Spring Boot开始根据类路径设置,其他bean和各种属性设置添加bean。
4.通常你会添加@EnableWebMvc一个Spring MVC应用程序,但Spring Boot会在类路径上看到spring-webmvc时自动添加它。这会将应用程序标记为Web应用程序并激活关键行为,例如设置a DispatcherServlet。
5.@ComponentScan告诉Spring在包中寻找其他组件,配置和服务hello,允许它找到控制器。

SpringBoot 常用注解

注解列表

个人觉得springboor中常用的注解主要可以分为三种:放入容器型注解、从容器中取出型注解和功能型注解。其中的放入容器型和从容器中取出型就是我们平时所说的控制反转和依赖注入的概念(个人版本- - - 可以看一看,别太当真 0.0)

放入容器型注解

简介:个人觉得就是申明一个实例对象,然后将这个对象交给spring管理。

1、@Component:放在类上,把普通类实例化到spring容器中。可以说很多注解都是基于这个注解的。

2、@Bean: 放在方法上,用@Bean标注方法等价于XML中配置bean,这个方法一般返回一个实体对象,告诉spring这里产生一个对象,然后这个对象会交给Spring管理。产生这个对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的容器中。

3、@Configuration:标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。(其实就是靠@Component注解)

4、@ConfigurationProperties:将配置文件中的参数映射成一个对象,通过prefix来设定前缀,然后将后面的和对象的属性名一致就能实现注入(当然这个对象需要注入的属性需要提供get和set方法 - - - 因为spring底层其实就是通过反射调用该对象的set方法)

5、@Value : value的作用其实和ConfigurationProperties作用差不多,就是读取配置文件中参数的值,但是value是放在变量上面的,且是单值读取,还有一点就是value标注的变量并不需要和配置文件的参数名字一致。注意我们在配置文件中是没有注明变量类型的,而是在使用的时候定义的。

6、@RestController、@Controller、@Service、@Repository:
        这四个注解熟悉吗?我想大家一定知道这四个注解各自的作用,但是这里需要强调一点就是他们其实是一样的,至少在spring5.x之前,他们实质上是没有什么区别的(当然你非要说@RestController=@Controller+@ResponseBody 这个也对)。我这边主要是要强调,他们实质上都是依靠于@Component注解的,我们可以查看源码。

我们可以看到Service 和Controller 这两个注解里面的东西是一模一样的,没什么区别。我不知道你们有没有做过这样的骚操作:就是在controller层中不用@Controller,而用@Service;在service中不用@Service,而用@Controller。其实这样写对于spring本身来说是没什么区别的,而且项目也能正常运行,这里我是亲自测过的。。。据说分为这三个注解的目的是为了从结构上分层。

从容器中取出型注解

简介:个人觉得就是我们平时所说的依赖注入。

1、@Resource:是按照名称来注入的,当找不到与名称匹配的bean才会按照类型来注入。其实我们平时用的@Resource都是用了他的默认的方式,即都不指定名字和类型。spring通过反射机制使用byName方法自动注入。
@Resource 的装配顺序:
1. 如果同时指定了 name 属性和 type 属性,那么 Spring 将从容器中找唯一匹配的 bean 进行装配,找不到则抛出异常
2. 如果指定了 name 属性值,则从容器中查找名称匹配的 bean 进行装配,找不到则抛出异常
3. 如果指定了 type 属性值,则从容器中查找类型匹配的唯一的 bean 进行装配,找不到或者找到多个都会抛出异常
4. 如果都不指定,则会自动按照 byName 方式进行装配(我们一般都用的是这个。。。)

2、@Autowried:默认是按照类型进行装配注入,如果允许 null 值,可以设置它 required 为false。即:当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false) ,这等于告诉 Spring:在找不到匹配 Bean 时也不报错。

@Autowired(required = false)
private ShiroService shiroService;

3、@Qualifier:@Autowired是根据类型进行自动装配的。如果当spring上下文中存在不止一个A类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在A类型的bean,而且我们又使用A类型,也会抛出BeanCreationException异常。针对存在多个A类型的Bean,我们可以联合使用@Qualifier和@Autowired来解决这些问题。

@Autowried
@Qualifier("adminDAO")
private AdminDAO adminDAO;

简单来说,Qualifier就是规定一下Bean的名字,相当于@Resource规定了name属性。

功能型注解
1、@SpringBootApplication:这个注解就是集成了:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解。其中@SpringBootConfiguration:表示这个类为配置类;@EnableAutoConfiguration:表示开启自动配置,我们平时所说springboot无配置就是这个参数起的作用,他读取了springboot默认的配置;@ComponentScan:表示自动扫描,这个扫描默认只能扫同一级的目录。

2、@EnableConfigurationProperties:将带有@ConfigurationProperties注解的类注入为Spring容器的Bean。如果使用了@ConfigurationProperties但是没有在启动类上增加这个注解,则@ConfigurationProperties将不起作用。

3、@Async与@EnableAsync:其中@Async表示这个方法为异步方法;@EnableAsync这个注解需要加在启动类上,表示支持异步操作;如果不加,则@Async将不起作用。

注解名 含义 注解名 含义
@SpringBootApplication 包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解 @Configuration 等同于spring的XML配置文件;使用Java代码可以检查类型安全。
@EnableAutoConfiguration 自动配置。你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。 @ComponentScan 组件扫描,可自动发现和装配一些Bean。如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。
@Component 可配合CommandLineRunner使用,在程序启动后执行一些基础任务。 @RestController @Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。
@Autowired 自动导入依赖的bean @PathVariable 获取参数。
@JsonBackReferenc 解决嵌套外链问题。 @JsonBackReferenc 配合spring-boot-starter-data-rest使用。
@Service 一般用于修饰service层的组件。 @Value 注入Spring boot application.properties配置的属性的值。

JPA注释

1.@Entity:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略
2.@Column:如果字段名与列名相同,则可以省略。
3.@Id:表示该属性为主键。
4.@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = “repair_seq”):表示主键生成策略是sequence(可以为Auto、IDENTITY、native等,Auto表示可在多个数据库间切换),指定sequence的名字是repair_seq。

springMVC相关注解

1.@RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。
用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
params:指定request中必须包含某些参数值是,才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
value:指定请求的实际地址,指定的地址可以是URI Template 模式
method:指定请求的method类型, GET、POST、PUT、DELETE等
consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

2.@RequestParam:用在方法的参数前面。
@RequestParam
String a =request.getParameter(“a”)。

3.@PathVariable:路径变量。参数与大括号里的名字一样要相同。

SpringBoot官方文档 2.1.3

基础知识

1.Spring Boot依赖项使用org.springframework.boot groupId。通常,您的Maven POM文件继承自spring-boot-starter-parent项目并声明对一个或多个“Starters”的依赖关系。
这spring-boot-starter-parent是使用Spring Boot的好方法,但它可能并不适合所有时间。有时您可能需要从不同的父POM继承,或者您可能不喜欢我们的默认设置。在这些情况下,请参见 第13.2.2节“使用没有父POM的Spring Boot”来获得使用import 范围的替代解决方案。

2.各种starter可以将jar添加到类路径中。

3.RestController和@RequestMapping
作为学到的第一个注释@RestController,被称为 构造型注释。既为阅读代码的人提供了提示,也为Spring提供了特定角色的提示。在这种情况下,我们的类是一个Web @Controller,因此Spring在处理传入的Web请求时会考虑它。
@RequestMapping注释提供“路由”的信息。它告诉Spring,任何带/路径的HTTP请求都应该映射到该home方法。而类前的 @RestController注解告诉Spring使得到的字符串直接返回给调用者。

4.第二个类级注释是@EnableAutoConfiguration。这个注释告诉Spring Boot根据你添加的jar依赖关系“猜测”你想要如何配置Spring。自从spring-boot-starter-web添加了Tomcat和Spring MVC 以来,自动配置假定您正在开发Web应用程序并相应地设置Spring。

5.启动器(starter)是一组方便的依赖关系描述符。在应用程序中引用这些描述符就能获得相关的Spring技术一站式服务。例如,如果要开始使用Spring和JPA进行数据库访问,请spring-boot-starter-data-jpa在项目中包含依赖项。这里的starter就是启动器。当然前面有springboot的才是官方的,其他的都是第三方的启动器。

6.当一个类不包含package声明时,它被认为是在“默认包”中。通常不鼓励使用“默认包”,应该避免使用。这可能会导致使用了Spring启动应用程序的特殊问题@ComponentScan,@EntityScan或@SpringBootApplication注解,因为从每一个罐子每一个类被读取。
我们建议您遵循Java推荐的包命名约定并使用反向域名(例如,com.example.project)。

7.主应用程序类放在其他类之上的根包中。该@SpringBootApplication注解往往放在你的主类,它需要放在根目录来搜索所有的类。

8.Spring Boot支持基于Java的配置。尽管可以使用 SpringApplicationXML源,但我们通常建议您的主要源是单个@Configuration类。通常,定义main方法的类是主要的候选者@Configuration。
当然你不需要把所有的@Configuration东西都放在一个类里,可以使用 @ComponentScan自动获取所有Spring组件,包括 @Configuration类。
如果您绝对必须使用基于XML的配置,我们建议您仍然从一个@Configuration类开始。然后,您可以使用@ImportResource注释来加载XML配置文件。

9。自动装配。Spring Boot自动配置尝试根据您添加的jar依赖项自动配置Spring应用程序。例如,如果HSQLDB 在您的类路径上,并且您尚未手动配置任何数据库连接bean,则Spring Boot会自动配置内存数据库。
您需要通过向其中一个类添加@EnableAutoConfiguration或 @SpringBootApplication注释来选择自动配置@Configuration。
您应该只添加一个@SpringBootApplication或@EnableAutoConfiguration 注释。我们通常建议您仅将一个或另一个添加到主 @Configuration类。

10.您可以自由地使用任何标准的Spring Framework技术来定义bean及其注入的依赖项。为简单起见,我们经常发现使用 @ComponentScan(找到你的bean,注意该注解不能单独使用)和使用@Autowired(做构造函数注入)效果很好。当然如果bean有一个构造函数,则可以省略@Autowired
如果按照上面的建议构建代码(在根包中定位应用程序类),则可以添加@ComponentScan不带任何参数的代码。您的所有应用程序组件(的@Component,@Service,@Repository,@Controller等)自动注册为bean。

11.@SpringBootApplication 自动配置、组件扫描、导入配置,三合一。

12.有需要时,我们可以自定义SpringApplication进行设置,例如关闭横幅、自动创建监听器、上下文刷新等配置选项。

13.使用ApplicationRunner或CommandLineRunner,这两个接口以相同的方式工作并提供单个run方法,该方法在SpringApplication.run(…​)完成之前调用 。

14.SpringBoot允许外部化配置,即使用@Value,注入Spring boot application.properties配置的属性的值。或者被 绑定到结构化对象通过@ConfigurationProperties。

15.使用@Value("${property}")注释注入配置属性有时会很麻烦,尤其是在使用多个属性或数据本质上是分层的情况下。Spring Boot提供了一种使用属性的替代方法,该方法允许强类型bean管理和验证应用程序的配置,即get、set方法。
有些人使用Project Lombok自动添加getter和setter。确保Lombok不为此类型生成任何特定构造函数,因为容器会自动使用它来实例化对象。
最后,仅考虑标准Java Bean属性,并且不支持对静态属性的绑定。

16.Spring Boot尝试在绑定到@ConfigurationPropertiesbean 时将外部应用程序属性强制转换为正确的类型。如果需要自定义类型转换,则可以提供ConversionServicebean(带有bean命名conversionService)或自定义属性编辑器(通过CustomEditorConfigurerbean)或自定义Converters(带有注释为bean的bean定义@ConfigurationPropertiesBinding)。

17.国际化。Spring Boot支持本地化消息,以便您的应用程序可以满足不同语言首选项的用户。默认情况下,Spring Boot会messages在类路径的根目录中查找资源包的存在。只要找到资源包就能去支持不同的语言。

18.静态内容。默认情况下,Spring Boot从类路径中的/static( /public或/resources或/META-INF/resources)目录或者根目录中提供静态内容ServletContext,当然也可以通过配置修改。同样index、Favicon也都可以通过配置修改。

19.动态内容。SpringBoot提供模板引擎,包括Thymeleaf,FreeMarker和JSP等。当您使用其中一个模板引擎和默认配置时,您的模板将自动从中获取src/main/resources/templates。

20.跨源资源共享 (CORS)是大多数浏览器实现 的W3C规范,允许您以灵活的方式指定授权何种跨域请求,而不是使用一些安全性较低且功能较弱的方法,如IFRAME或JSONP。在Spring Boot应用程序中使用带有 注释的控制器方法CORS配置@CrossOrigin不需要任何特定配置。 可以通过使用自定义方法注册bean 来定义全局CORS配置。

21.OAuth2。OAuth2是Spring支持的一种广泛使用的授权框架。

22.由于Spring Boot依赖于Spring Security的默认值,因此默认情况下会启用CSRF保护。这意味着执行器端点需要POST(关闭和记录器端点),PUT或者DELETE在使用默认安全配置时将获得403禁止错误。

JPA

1.在Spring框架提供了广泛的支持使用使用SQL数据库,直接JDBC访问JdbcTemplate来完成“对象关系映射”技术,比如Hibernate。Spring Data提供了更多级别的功能:Repository直接从接口创建实现,并使用约定从方法名称生成查询

2.JPA是一种标准,可以让对象“映射”到关系数据库。。而spring-boot-starter-data-jpaPOM提供了上手的快捷方式。它提供以下关键依赖项:
Hibernate:最受欢迎的JPA实现之一。
Spring Data JPA:使实现基于JPA的存储库变得容易。
Spring ORMs:Spring Framework的核心ORM支持。

3.实体类。传统上,JPA“实体”类在persistence.xml文件中指定。使用Spring Boot,此文件不是必需的,而是使用“实体扫描”。默认情况下,将搜索主配置类(注释为@EnableAutoConfiguration或者@SpringBootApplication)下的所有包 。任何类别标注了@Entity,@Embeddable或者@MappedSuperclass被认为是实体类。
您可以使用@EntityScan注释自定义实体扫描位置。

4.Spring Data JPA存储库。Spring Data JPA存储库是您可以定义以访问数据的接口。JPA查询是从您的方法名称自动创建的。例如, CityRepository接口可能会声明一种findAllByState(String state)方法来查找给定状态中的所有城市。
即根据方法名自动生成的接口。对于更复杂的查询,您可以使用Spring Data的Query注释来注释您的方法 。

Spring Data存储库通常从Repository或 CrudRepository 接口扩展 。如果使用自动配置,则会从包含主配置类(带有@EnableAutoConfiguration或标注的@SpringBootApplication)的包中搜索存储库 。

5.Spring Data JPA存储库支持三种不同的引导模式:default,deferred和lazy。要启用延迟或延迟引导,请分别设置 spring.data.jpa.repositories.bootstrap-mode为deferred或lazy。使用延迟或延迟引导时,自动配置EntityManagerFactoryBuilder 将使用上下文(AsyncTaskExecutor如果有)作为引导程序执行程序。如果存在多个,则applicationTaskExecutor使用命名的那个。

Spring Data Jpa 官方文档,重要!

6.Spring Data JDBC。Spring Data包含对JDBC的存储库支持,并将自动为方法生成SQL CrudRepository。对于更高级的查询,@Query提供了注释。
当必要的依赖项在类路径上时,Spring Boot将自动配置Spring Data的JDBC存储库。它们可以通过单个依赖项添加到项目中spring-boot-starter-data-jdbc。如有必要,您可以通过向应用程序添加@EnableJdbcRepositories注释或 JdbcConfiguration子类来控制Spring Data JDBC的配置。

生产就绪功能

1.发布时自定义前缀、端口、监控

2.SpringBoot在注册时可以设定的指标:JVM指标、CPU指标、文件描述符指标、Tomcat指标等等

3.Spring Boot支持的大多数模板技术都包含一个禁用缓存的配置选项(本文档后面会介绍)。如果使用该 spring-boot-devtools模块, 则会在开发时自动为您配置这些属性 。如果您使用Thymeleaf,请设置spring.thymeleaf.cache为false(否则你改了网页也显示不出来)。查看 ThymeleafAutoConfiguration 其他Thymeleaf自定义选项。

4.properties文件中所有属性含义见链接