本文是读《Spring Boot2精髓-从构件小系统到架构分布式大系统》的读书笔记。
JavaEE对于如下的功能需求,有相应的规范实现与之对应:
Web支持:Servlet规范,规定了Web容器、Servlet组件。
事务支持:JavaEE提供了JTA事务API和JTS事务服务规范。
消息服务:JavaEE提供了JMS服务。
数据库持久层:JavaEE先有EJB规范,后有JPA。
Container:提供了WebContainer,用于实现了Servlet,以及EJB Container,实现EJB。
缺点:过于复杂、追求分布式、不能及时与流行开源技术结合、JavaEE应用服务器通常由商业 公司提供,价格不菲。
Spring,建立在JavaEE的基础上, 同样可以使用JavaEE的功能,并且使开发并部署网站和企业应用变得简单。它提供了一个IoC容器来管理Bean,并通过AOP方式来增强Bean的功能。
控制反转(IoC)和面向切面(AOP),来提供任意的服务和增强Bean的任意特性。可通过Bean管理来无限扩展功能 。
IoC Core Container:
用注解@Controller声明的对象,Spring会认为这个 对象是个Web Controller ,如果这个对象里的方法有@RequestMapping注解 ,则将客户端发起的HTTP请求转化成Java方法调用。
package com.bee.sample.ch1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.bee.sample.ch1.annotation.Function;
/**
* 访问:http://127.0.0.1:8080/sayhello.html?name=springboot
*
*
*/
@Controller
public class HelloworldController {
@RequestMapping("/sayhello.html")
@Function()
public @ResponseBody String say(String name){
return "hello "+name;
}
}
AOP技术:
(Aspect Oriented Programming)通过预编译方式或者运行时刻对目标对象动态地添加功能 。比如 要实现用户访问控制,可以对每个Controller的方法使用一个自定义的注解Function,用Spring AOP向Controller每个方法动态地添加用户权限校验功能。
缺点:使用门槛高、对过时技术兼容导致使用复杂度升高、XML已经不流行、集成第三方工具时,要考虑兼容、系统启动慢、不具备热部署功能、完全依赖虚拟机或Web服务器的热部署。
不需要配置就能运行Spring应用,Spring boot管理Spring容器、第三方插件,并提供很多默认系统级的服务。
通过Starter来提供 系统级服务,提供 了一系列的Starter,也可以自己开发,只要在pom.xml中声明一下就可以。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
例如 :
spring-boot-starter-web Web开发支持,默认使用 Tomcat8
spring-boot-starter-aop AOP开发支持,使用AspectJ
spring-boot-starter-data-redis 集成redis,使用JRedis,默认连接localhost:6379
优点:
package com.bee.sample.ch1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication//添加注解使其成为Spring Boot的一个类
public class Ch1Application {
public static void main(String[] args) {
SpringApplication.run(Ch1Application.class, args);
}
}
Controller:
package com.bee.sample.ch1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.bee.sample.ch1.annotation.Function;
/**
* 访问:http://127.0.0.1:8080/sayhello.html?name=springboot
*
* */
@Controller
public class HelloworldController {
@RequestMapping("/sayhello.html")
@Function()
public @ResponseBody String say(String name){
return "hello "+name;
}
}
使用热部署:
Spring Boot提供了sping-boot-devtools,能在修改类或者配置文件的时候自动加载Spring Boot应用。
Spring Boot会检测到class文件变化 ,重启。再次重启时,避免了重启Tomcat Server,只重新加载变化 的类,所以速度很快。
添加REST支持:
系统是由多个系统构成,系统之间的调用方式很多,RESTFul也是一种很好 的方式,
package com.bee.sample.ch1.rest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 注解RestController相当于注解Controller和ResponseBody的合体。
* 试试诡异制造如下问题:
* 1 更改getCreditLevel名字为getCreditLevelTest
* 2 /usercredit/{id} 更改为 /usercredit/{id1}
*
*
*/
@RestController
public class UserReditRestController {
@RequestMapping(value="/usercredit/{id}")
public Integer getCreditLevel(@PathVariable String id) {
return Integer.parseInt(id);
}
}
Maven是项目构建工具,能把项目抽象成POM(project object model),Maven使用POM对项目进行构建、打包、文档化等操作
从maven.apache.org
上下载最新的Maven
可以使用aliyun的maven镜*像
Spring Cloud系列是炙手可热的技术 ,是基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式 ,目前,市场上的实现 的微服务 架构,主要是联合这两种技术 。
Spring容器介绍
IoC(Inversion of Control,反向控制),更为形象的称呼是DI(dependency injection,依赖注入)
Spring框架是根据Bean之间的依赖关系创建对象,并注入到Bean(组件)中。
bean就相当于定义一个组件,这个组件是用于具体实现某个功能的。这里的所定义的bean就相当于给了你一个简洁方便的方法来调用这个组件实现你要完成的功能。
在Spring中,从BeanFactory或ApplicationContext取得的实例被默认为Singleton,也就是默认每一个Bean名称只维持一个实例。scope属性预设是"singleton",通过将其设置为"prototype",使得每次指定名称来取得Bean时,都会产生一个新的实例。也可以设置"singleton"属性为true或false,来设置以Singleton的方式产生实例,这种方式主要与以前的版本兼容而保留的。
Spring的Singleton主要是针对"一个IoC容器维持一个Bean实例"而言的。与设计模式上谈到的Singleton不同,设计模式上谈到的Singleton,是指对每个ClassLoader所载入的类产生一个实例。
Spring2.0中,scope除了可以设置"singleton" 与"prototype"之外,针对Web应用程序环境,还可以设置"request"、"session"与"globalSession",分别表示请求阶段、会话阶段与基于Portlet的Web应用程序会话阶段。
常用注解
@Service
public class ExampleBean{
}
@Service
public AnotherExampleBean{
@Autowried ExampleBean bean;
}
Spring AOP介绍
面向切面编程,(Aspect Oriented Programming),
Spring Boot中使用AOP
引入AOP依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bee.sample</groupId>
<artifactId>ch2.aop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编写一个AOP切面类:
package com.bee.sample.ch2.conf;
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
/**
* Controller 的所有方法在执行前后都会进入functionAccessCheck方法
*
*
*/
@Aspect//Aspect,声明这是一个切面类
@Configuration
public class AOPConfig {
@Around("@within(org.springframework.stereotype.Controller) ")
public Object functionAccessCheck(final ProceedingJoinPoint pjp) throws Throwable {
try {
Object[] args = pjp.getArgs();
System.out.println("args:"+Arrays.asList(args));
Object o = pjp.proceed();
System.out.println("return :"+o);
return o;
} catch (Throwable e) {
throw e;
}
}
}