Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置。简单来说,它提供了一堆依赖打包,并已经按照使用习惯解决了依赖问题---习惯大于约定。

Spring Boot提供了一系列的依赖包,所以需要构建工具的支持:maven 或 gradle。

使用:
① 新建一个maven项目。

② pom中parent设为 spring-boot-starter-parent 。建议使用最新的 RELEASE 版本。否则可能需要设置 和 。

③ 添加应用需要的starter模块,

这里添加的starter模块就相当于一系列依赖包,maven会去自动下载相应的依赖包到本地仓库。
保存pom,刷新maven,以便刷新依赖导入。
基本上,如果没有特别的需要,现在就可以直接写Controller了!!!--特别的需要 是指设置容器、访问端口、路径等。后面再解释。

SpringApplication 则是用于从main方法启动Spring应用的类。默认,它会执行以下步骤:

创建一个合适的ApplicationContext实例 (取决于classpath)。
注册一个CommandLinePropertySource,以便将命令行参数作为Spring properties。
刷新application context,加载所有单例beans。
激活所有CommandLineRunner beans。
默认,直接使用SpringApplication 的静态方法run()即可。但也可以创建实例,并自行配置需要的设置。

如果你理解了ComponentScan,你就理解了Spring.
Spring是一个依赖注入(dependency injection)框架。所有的内容都是关于bean的定义及其依赖关系。
定义Spring Beans的第一步是使用正确的注解-@Component或@Service或@Repository.
但是,Spring不知道你定义了某个bean除非它知道从哪里可以找到这个bean.
ComponentScan做的事情就是告诉Spring从哪里找到bean

SpringBoot注解

[toc]

当然你在用每个注解前要导入相应的包。即各种import,当然你在用到这个注解时,alt+enter也可以完成自动导包。另外IDEA在编码前也可以设置自动导包。

启动、config类

启动类,主要完成自动扫描、自动注册、事务支持。

@ServletComponentScan(basePackages = "com.bw.ae.datacenter.announcement") 在SpringBootApplication上使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。)如果Application类和Servlet类不在同一包下,则@ServletComponentScan需要添加相应的路径。

@ComponentScan(basePackages = "com.bw.ae.datacenter.announcement") 由你来定义哪些包需要被扫描。一旦你指定了,Spring将会将在被指定的包及其下级的包(sub packages)中寻找bean。包扫描会扫描只要标注了@Controller,@Service,@Repository,@Component这四个注解都会被扫描到容器中。

@EnableTransactionManagement(order = 2) 开启事务支持,使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。

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

@EnableAutoConfiguration

@EnableScheduling @Scheduled与@EnableScheduling: 定时任务。@EnableScheduling这个注解需要加在启动类上,表示支持定时任务。比如:定期推送某些信息给用户。现在实现定时任务的方法,很多人使用的是 quartz,而 SpringBoot 自带的两个注解就可以轻松搞定@Scheduled与@EnableScheduling

config类,主要完成各种配置文件的读入。

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

@EnableTransactionManagement 开启事务支持,使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。

@EnableJpaRepositories @EnableJpaRepositories注解用于Srping JPA的代码配置,用于取代xml形式的配置文件,

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

@Qualifier("announcementDataSource") @Autowired是根据类型进行自动装配的。如果当spring上下文中存在不止一个A类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在A类型的bean,而且我们又使用A类型,也会抛出BeanCreationException异常。针对存在多个A类型的Bean,我们可以联合使用@Qualifier和@Autowired来解决这些问题。简单来说,Qualifier就是规定一下Bean的名字,相当于@Resource规定了name属性,即按照名称进行注入。

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

@Primary 在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了。用@Primary 告诉spring 在犹豫的时候优先选择哪一个具体的实现。当然用@Qualifier这个注解也能来解决问题。

@Value("${announcement.dir}") value的作用其实和ConfigurationProperties作用差不多,就是读取配置文件中参数的值,但是value是放在变量上面的,且是单值读取,还有一点就是value标注的变量并不需要和配置文件的参数名字一致。但是配置文件中的参数和value表达式中的参数名字是要保持一致的,即announcement.dir都有。

AOP编程:

@Aspect AOP编程引申出来的东西,在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
@Aspect:作用是把当前类标识为一个切面供容器读取,即表示这是一个切面类。

@Component 放在类上,把普通类实例化到spring容器中,然后Spring就可以把这个类当做一个容器来用了。可以说很多注解都是基于这个注解的。

@Pointcut("execution(public * com.bw.ae.datacenter.announcement.controller...(..))") AOP编程中使用,Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。

@Around(" Oauth() && @annotation(oauth) ") AOP编程中使用,环绕增强,相当于MethodInterceptor。
切面类还有注解为:
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行

bean、pojo、dao、dto层

bean层,容器中要使用的Java对象。

@Data 这个注解来自于 lombok,lombok 能够减少大量的模板代码,减少了在使用@Data 注解时, 需要导入lombok.Data,下面列举下 lombok提供的注解:@Data : 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法

@Override 重写方法。

POJO层 DO(业务实体对象),数据表到实体类的映射。DO 对象对内,主要完成实体对象的映射。是数据库一条记录映射成的java对象,仅表示数据,没有任何数据操作。

@Data 这个注解来自于 lombok,lombok 能够减少大量的模板代码,减少了在使用@Data 注解时, 需要导入lombok.Data,下面列举下 lombok提供的注解:@Data : 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法

@Entity
@Table(name = "admin") @Entity注解在类上表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略

@Id 表示该属性为主键。

@GeneratedValue(strategy = GenerationType.IDENTITY) 用于标注主键的生成策略,通过 strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 identity,MySQL 对应 auto increment。IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;AUTO: JPA自动选择合适的策略,是默认选项;

@Transient 表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。@Basic(fetch=FetchType.LAZY):标记可以指定实体属性的加载方式

@Override 重写比较方法

dao层,这里全部是接口,即完成pojo层对象的增删改查。也正如规定的一样,接口名字末尾加上了Dao来表示具体的功能。 主要完成标记数据访问组件。数据访问对象,进行数据库增删改查操作。

@Repository @Controller、@Service、@Repository这三个注解底层实现是一样的,并且三者都继承自@Component,据说分为这三个注解的目的是为了从结构上分层。通常一些类无法确定是使用@Service还是@Component时,注解使用@Component,比如redis的配置类等

@Query 自定义查询语句 JPQL。
在Spring框架中,关于从数据表获取数据有不同的方法,当数据查询比较简单时,可以通过继承JpaRepository<T, L> 使用findBy*** 方法,通过分析方法名来实现查询,T表示要查询的数据表所对应的实体,L表示该实体主键的类型,比如Long。关于findBy方法如何通过分析方法名来实现查询
如果查询的数据比较复杂,查询条件比较复杂时,可以考虑使用JPA的@query方法来实现查询。1.首先Dao层需继承Repository<T, L>,T为实体名,L为该实体的主键类型。 2.写查询方法,并使用@query进行注解。

JpaRepository分两种:1.预先生成方法,即一片空白,spring data jpa 会预先生成增删改方法 2.使用默认方法,即findAll、findOne、save这种,自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称:还会加分页、排序、限制个数等参数。也可以使用@Query来指定本地查询。

dto层,DTO(数据传输对象),可视为多个pojo对象的组合。需要在mapper层中添加设置。DTO对象对外,主要完成业务对象的映射,可以根据业务需要变更,并不需要映射 DO 的全部属性。于是我们用主要完成完成对象与对象之间的转换。前端传输时调用。

@ApiMode @ApiModelProperty(这两个都是来自swagger插件的)

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。Swagger的目标是对REST API定义一个标准的和语言无关的接口,可让人和计算机无需访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过Swagger进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger消除了调用服务时可能会有的猜测。

访问地址/swagger-ui.html

作用范围API使用位置
对象属性@ApiModelProperty用在出入参数对象的字段上
协议集描述@Api用于controller类上
协议描述@ApiResponses用在controller的方法上
Response集@ApiResponses用在controller的方法上
Response@ApiResponse用在 @ApiResponses里边
非对象参数集@ApiImplicitParams用在controller的方法上
非对象参数描述@ApiImplicitParam用在@ApiImplicitParams的方法里边
描述返回对象的意义@ApiModel用在返回对象类上

使用步骤:
1.添加pom依赖,编写配置文件(Swagger2Config.java)。
2.添加文档内容(一般上是在Controller,请求参数上进行注解)。
3.完成配置,启动后访问页面即可。即配置完model、controller层即可进行查看api。
4.用户在页面输入对应参数即可直接在页面上调试。

service层

service层,主要完成dao注入,用于业务的逻辑处理。主要分两类,即service后缀的接口和lmpl后缀的类。spring鼓励应用程序的各个层以接口的形式暴露功能,在service层,可以使用service接口+serviceImple实现类,也可以使用service类,但考虑到“接口时实现松耦合的关键”,所以更加推荐使用。service接口+serviceImple实现类的方式来写service层代码。当然一些业务通用的service虽然也放在lmpl里面,但是是不加lmpl后缀,而是加service后缀的。

service后缀的接口没有注解,它只需要声明我需要的实现方法就行,所以只有get、change、create、news、history、save、delete前缀的各种方法,即我接下来lmpl里面要实现的各种方法。

lmpl后缀的类,最为关键的地方,这里要引入bean层、dao层、pojo层和相应的service。

在dao层的简单增删改查基础上完成更加复杂的操作,都靠impl实现,实现完后把方法封装到service中,给controller调用。事实上dao层属于一种比较底层,比较基础的操作,具体到对于某个表、某个实体的增删改查。
service层里面的方法相较于dao层中的方法进行了一层包装,例如通过id查找用户,通过用户名查找用户,是在基础的操作上又增加了一层包装的,实现的是相对高级的操作。最后将这些操作在serviceimpl类中实现。这样进行分层,访问数据库和进行service之间的分工明确,如果我需要对service的需求修改,无需改变dao层的代码,只要在实现上改变即可,如果我有访问数据库的新需求,那我也只要在dao层的代码中增添即可。

@Service
@Autowired
@Override

controller层

controller层,控制器层,主要完成注入服务。对相应的url请求,给与相应的服务与返回值,需要引入bean层、config层、dao层、pojo层、executor层、util层、service层。controller层,在接收到url后,调用相应的service方法,并准备返回网页及状态码。同时完成权限设置,定时触发任务等功能。

@RestController @Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

@RequestMapping("/admin") 和请求报文是做对应的

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

@Value("${localserver.address}") value的作用其实和ConfigurationProperties作用差不多,就是读取配置文件中参数的值,但是value是放在变量上面的,且是单值读取,还有一点就是value标注的变量并不需要和配置文件的参数名字一致。但是配置文件中的参数和value表达式中的参数名字是要保持一致的,即localserver.address都有。

@ApiOperation(value = "管理员公告历史列表", notes = "管理员公告历史列表") swagger插件使用

@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "Token", dataType = "String"),
@ApiImplicitParam(name = "pagenum", value = "页码", dataType = "String"),
@ApiImplicitParam(name = "viewstatus", value = "查看的公告状态类型", dataType = "String"),
@ApiImplicitParam(name = "delannouncementid", value = "需要删除的公告id", dataType = "String")
})

@RequestMapping(value = "/historylist", method = RequestMethod.POST) 和请求报文是做对应的

@Oauth(type = OauthType.ANNOUNCEMENT_ADMIN)

@Scheduled(fixedDelay = 60 * 1000) 定时,某个时间间隔下完成注解下面的相应任务。

public void postFile(@PathVariable(name = "name") String name, @RequestBody byte[] content) {} @PathVariable:路径变量。参数与大括号里的名字一样要相同。用来接收参数,如这里可接受url中的对应数据作为name参数

@RequestBody和@ResponseBody
@RequestBody注解允许request的参数在reqeust体中,常常结合前端POST请求,进行前后端交互。
@ResponseBody注解支持将的参数在reqeust体中,通常返回json格式给前端。

exception报错层

exception层,主要完成项目中的报错处理。
@ControllerAdvice(annotations = RestController.class) 在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。拦截所有控制器的异常可以在一个地方进行处理。

@ResponseBody 该注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上@Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。

@ExceptionHandler(UserAuthException.class) 之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑:Spring能够较好的处理这种问题,核心如下:

@ExceptionHandler:统一处理某一类异常,从而能够减少代码重复率和复杂度
@ControllerAdvice:异常集中处理,更好的使业务逻辑与异常处理剥离开
@ResponseStatus:可以将某种异常映射为HTTP状态码

@ResponseStatus(HttpStatus.UNAUTHORIZED) @ResponseStatus 用于修饰一个类或者一个方法,修饰一个类的时候,一般修饰的是一个异常类,如下,声明一个异常类在类上面加上ResponseStatus注解,就表明,在系统运行期间,抛出AuthException的时候,就会使用这里生命的 error code 和 error reasoon 返回给客户端,提高可读性。

@ResponseBody 该注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上@Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。

filter、executor、util工具类,mepper类

filter工具类,完成登录验证、防XSS攻击、定时清除缓存的功能
executor工具类,完成格式转换、国际化、文件预览、文件压缩解压等功能。
util工具类,完成附件上传、属性信息、Session权限管理、公钥私钥等功能。
mapper类,把多表的字段自动映射到DTO实体实例的指定字段中。由于依赖中有实体映射工具MapStruct的依赖。所以才能使用这个功能。
@Mapper(componentModel = "spring") 声明Mapper接口使用Spring配置方法, 添加了@Mapper注解之后这个接口在编译时会生成相应的实现类

@Mappings({
@Mapping(source = "id", target = "announcementid"),
})

MapStruct 就是这样的一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。它可以将一种类型的对象中的部分转换为另一种对象,也可以将几种类型的对象映射为另外一种类型,比如将多个 DO 对象转换为 DTO。

MapStruct 使用过程:
1.创建DTO类,DTO中需要其他多表的信息。
2.创建Mapper。@Mapper注解是用于标注接口,只有存在该注解才会将内部的接口方法自动实现。
3.填写Mapper方法,这里有默认和Spring方式配置两种,使用Spring配置后,在外部可以采用@Autowired方式注入Mapper实现类完成映射方法调用。
4.填写@Mappings & @Mapping。@Mapping注解我们用到了两个属性,分别是source、target。source代表的是映射接口方法内的参数名称,如果是基本类型的参数,参数名可以直接作为source的内容,如果是实体类型,则可以采用实体参数名.字段名的方式作为source的内容。target代表的是映射到方法方法值内的字段名称。
以上四步就完成了MapStruct的调用。MapStruct根据我们配置的@Mapping注解自动将source实体内的字段进行了调用target实体内字段的setXxx方法赋值,并且做出了一切参数验证。我们采用了Spring方式获取Mapper,在自动生成的实现类上MapStruct为我们自动添加了@ComponentSpring声明式注入注解配置。

除了注解之外的语句

1.JSONObject jsonObject

 public ResponseEntity<JSONObject> getdepartmentanduser(){
        JSONObject jsonObject = getDepartmentAndUserService.getdepartmentanduser();//直接构建一个JsonObject实例对象
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);//吧JSONObject对象当做返回结果。配合HTTP状态码返回。
    }

使用JSONObject生成的是JSONObject对象。

JSONObject obj = new JSONObject();
obj.put(key, value);
这里的意思则是实例化一个JSONObject对象,而后调用其put()方法,将数据写入。put()方法的第一个参数为key值,必须为String类型,第二个参数为value,可以为boolean、double、int、long、Object、Map以及Collection等。当然,double以及int等类型只是在Java中,写入到json中时,统一都会以Number类型存储。

2.鉴权,使用Auth,获取用户信息,tokens存放在redis中,准备验证。企业微信tokens验证。

3.ResponseEntity<>(jsonObject,HttpStatus.OK);这句里面有两个参数JSONObject和HttpStatus。这里我们使用ResponseEntity的主要目的是用它来响应json格式的数据。
ResponseEntity标识整个http相应:状态码、头部信息以及相应体内容。因此我们可以使用其对http响应实现完整配置。
如果需要使用ResponseEntity,必须在请求点返回,通常在spring rest中实现。ResponseEntity是通用类型,因此可以使用任意类型作为响应体:

替代方法
@ResponseBody
典型spring mvc应用,请求点通常返回html页面。有时我们仅需要实际数据,如使用ajax请求。这时我们能通过@ResponseBody注解标记请求处理方法,审批人能够处理方法结果值作为http响应体。

@ResponseStatus
当请求点成功返回,spring提供http 200(ok)相应。如果请求点抛出异常,spring查找异常处理器,由其返回相应的http状态码。对这些方法增加@ResponseStatus注解,spring会返回自定义http状态码。

4.private static final Logger logger = LoggerFactory.getLogger(AdminController.class);作用是指定类初始化对象,在日志输出的时候,可以打印出日志信息所在类。