概念
Spring的优缺点
1. 优点(AOP和IOC简化开发) Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的Enterprise JavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。 2. 缺点(配置繁琐和pom.xml的坐标引入麻烦) 1. 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。 2. 所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。 3. 除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。
SpringBoot
1. springboot解决spring的缺点: SpringBoot基于**约定优于配置**的思想,不必在配置与逻辑业务之间进行思维的切换,从而大大提高了开发的效率. 2. SpringBoot的特点: 1. 为基于Spring的开发提供更快的入门体验 2. 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求 3. 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等 4. SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式 3. 核心功能 1. 起步依赖(start dependence) 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。 简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。 2. 自动配置(auto configuration) SpringBoot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。
开始代码
快速开始
1. 创建普通的maven项目,简单的javase就好 2. 编写pom.xml文件 1. SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent2. SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖(以功能为单位的) org.springframework.boot spring-boot-starter-parent 2.0.5.RELEASE 3. 编写启动引导类(引导类放置的位置在创建项目时指定的groupid包下) package cn.wzlove; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 使用注解标注该类是SpringBoot的引导类 @SpringBootApplication public class MySpringBootApplication { public static void main(String[] args) { // run方法表示运行SpringBoot的引导类,参数是SpringBoot引导类的字节码文件 SpringApplication.run(MySpringBootApplication.class); } } 4. 编写Controller进行测试 @Controller public class QuickController { @RequestMapping("quick") @ResponseBody public String quickStart(){ return "quick start"; } } ==================================== 或者使用RestController @RestController public class HelloController { @RequestMapping("hello") public String hello(){ return "hello"; } } org.springframework.boot spring-boot-starter-web
SpringBoot的热部署
1. 添加功能坐标:2. idea的配置 file ---> setting,搜索compile,选中Compile,右侧会出现内容,这个时候选中Build project automatically.点击apply,点击ok 3. 快捷键ctrl+alt+shift+/,选中Registry,在aompiler.automake.allow.when.app.running后面打上对勾,之后关闭就好. org.springframework.boot spring-boot-devtools
idea快速创建SpringBoot项目
1. file创建工程,这个时候不要选择maven,而是选择Spring Initializr,点击下一步,输入Group和Artifact,下一步,选择依赖,目前先选择Web下的Web,下一步,就可以一完成创建了.
SpringBoot的原理分析:
起步原理分析
1. SpringBoot继承的起步依赖spring-boot-starter-parent查看源码可以看到默认加载resources下的以application开头的配置文件和各种插件,并且还继承了spring-boot-dependencies. 继续查看spring-boot-dependencies的源码,主要看 org.springframework.boot spring-boot-starter-parent 2.0.6.RELEASE 之间的内容,也就是版本控制,里面包含了各种依赖包的版本号,继续看 里面的内容,版本统一管理器. 这下就可以看出来继承的起步依赖主要是为了进行jar包的版本控制的.这样我们在pom文件中导入依赖就不需要指定版本了. 2. web工程的起步依赖所做的事 查看源码可以看到这个依赖内部引入了更多的依赖,比如过spring-web,spring-webmvc,json等等,传递依赖. org.springframework.boot spring-boot-starter-web
自动配置
1. 从@SpringBootApplication开始研究,自动配置就是从这开始的.查看源码主要看: // SpringBootConfiguration其实就是@Configuration,指定配置文件的 @SpringBootConfiguration // 自动配置 @EnableAutoConfiguration // 根据约定大于配置,所以默认的扫描包是启动类下及其子包下的所有Bean @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) 2. @EnableAutoConfiguration代表是否可以自动配置 ,查看源码主要看@Import(AutoConfigurationImportSelector.class),查看AutoConfigurationImportSelector类下的selectImports方法,看Listconfigurations = getCandidateConfigurations(annotationMetadata,attributes);其实应该就是全包名的集合,点进去看看,会让去查找META-INF/spring.factories下的这个文件,这个文件在当前类所在的包下,打开看看就是各种全类名.可以继续向下研究,查看各种AutoConfiguration类的源码
创建配置文件修改端口号和web应用的名称
resources下创建application.properties,内容为: # 设置启动端口号为8081 server.port=8081 # 当前web的应用名称 server.servlet.context-path=/springboot
SpringBoot的配置文件:
配置文件类型和作用:
1. 覆盖默认配置: SpringBoot是基于约定的,所以很多配置都有默认值,但如果想替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。 2. 配置额外信息,比如数据源等等 3. 配置文件放在resources目录下.默认加载application.properties或application.yml(application.yaml)文件 4. application.properties文件是键值对类型的文件.yml文件类似于json.
yml文件
1. YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。 2. YML文件的扩展名可以使用.yml或者.yaml。(SpringBoot是有默认加载顺序的,源码可以看到,先加载yml的,后加载yaml的,最后加载properties,后面的会覆盖前面的). 3. 语法形式: 1. 配置普通数据 name: wangzhi =====> 冒号后面有空格 2. 配置对象数据(person对象为例),两种,推荐第一种 person: name: zhangsan age: 18 addr: beijing ============================= person: {name: zhangsan,age: 18,addr: beijing} 3. 配置数组 普通数组: city: - beijing - tianjin - chongqing - shanghai ============================= city: [beijing,tianjin,chongqing,shanghai] 对象集合: student: - name: tom age: 18 addr: beijing - name: lucy age: 17 addr: yuncheng ============================ student: [{name: zhangsan,age: 18,addr: beijing},{name: tom,age: 18,addr: beijing}] 4. map配置: map: key1: value1 key2: value2 4. 测试注入: application.yml的内容为: name: wangzhi person: name: lucy age: 24 addr: 运城 代码内的注入(使用@Value注解): @Value("${name}") private String name; @Value("${person.addr}") private String addr; @Value("${person.age}") private int age; 代码内的注入方式2: 通过注解@ConfigurationProperties(prefix="配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映射,需要提供get和set方法 2. 执行器的配置(编写yml的文件的时候有代码提示,不配置也可以完成功能)org.springframework.boot spring-boot-configuration-processor true
SpringBoot与其他技术的整合
与Mybatis的整合
1. 添加Mybatis的起步依赖2. 添加数据库驱动坐标 org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.2 3. 添加数据库的连接信息(在resources下的application.properties添加内容): # 数据库的连接信息 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=nrblwbb7 4. 创建数据库和表结构: CREATE DATABASE test; USER test; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) DEFAULT NULL, `password` VARCHAR(50) DEFAULT NULL, `name` VARCHAR(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '张三'); INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四'); SELECT * FROM USER; 5. 创建实体类 public class User { // 主键 private Long id; // 用户名 private String username; // 密码 private String password; // 姓名 private String name; //此处省略getter和setter方法 .. .. } 6. 创建mapper接口 public interface UserMapper { List mysql mysql-connector-java queryUserList(); } 7. 创建映射配置文件(在resources下新建mapper文件夹,在下面创建UserMapper.xml) 8. 配置文件配置mybatis的信息: #spring集成Mybatis环境 #pojo别名扫描包 mybatis.type-aliases-package=cn.wzlove.domain #加载Mybatis映射文件 mybatis.mapper-locations=classpath:mapper/*Mapper.xml 9. 写个Controller进行代码测试 @RestController public class Controller { @Autowired private UserMapper userMapper; @RequestMapping("mybatis") public String testMyBatis(){ List users = userMapper.queryUserList(); System.out.println(users); return "success"; } }
与Junit的整合
1. 添加SpringBoot集成Junit测试的起步依赖(如果使用idea创建的话会直接引入,不需要重复导入)2. 编写测试类: // SpringRunner继承自SpringJUnit4ClassRunner,使用哪一个Spring提供的测试测试引擎都可以 @RunWith(SpringRunner.class) // classes后面的字节码是启动类的字节码 @SpringBootTest(classes = SpringbootMybatisApplication.class) public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testMyBatis(){ List org.springframework.boot spring-boot-starter-test test users = userMapper.queryUserList(); System.out.println(users); } }
与SpringDataJPA的整合
1. 添加Spring Data JPA的起步依赖2. 添加mysql连接驱动依赖 org.springframework.boot spring-boot-starter-data-jpa 3. 在application.properties中配置数据库和jpa的相关属性 # 配置数据库的连接信息 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql:127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=nrblwbb7 # 配置Spring Data JPA的相关信息 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update 4. 创建实体并使用springdatajpa进行配置 @Entity public class User { // 主键(mysql主键自增) @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 用户名 private String username; // 密码 private String password; // 姓名 private String name; //此处省略setter和getter方法... ... } 5. 创建repository接口(也就是dao) /** * @ClassName UserRepository * @Author wz157 * @Date 2018/10/19 23:18 * @Description TODO * 两个泛型,第一个是实体,第二个是主键类型 */ public interface UserRepository extends JpaRepository mysql mysql-connector-java { List findAll(); } 6. 创建测试类进行测试 @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringbootSpringdatajpaApplication.class) public class JpaTest { @Autowired private UserRepository userRepository; @Test public void testJps(){ List all = userRepository.findAll(); System.out.println(all); } } 7. 如果是jdk9可能报错,需要额外引入依赖 javax.xml.bind jaxb-api 2.3.0
与Redis的整合
1. 配置redis的起步依赖:2. 配置redis的连接信息(本地需要安装有Redis) #Redis spring.redis.host=127.0.0.1 spring.redis.port=6379 3. 编写测试类: @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringbootSpringdatajpaApplication.class) public class RedisTest { // 转化成json各执字符串 @Autowired private RedisTemplate org.springframework.boot spring-boot-starter-data-redis redisTemplate; @Autowired private UserRepository userRepository; @Test public void testRedis() throws JsonProcessingException { // 1. 从redis中获取数据,习惯json字符串 String userListJson = redisTemplate.boundValueOps("user.findAll").get(); // 2. 判断redis是否存在数据 if(null == userListJson){ // 3. 如果不存在数据,从数据库查询 List all = userRepository.findAll(); // 将查询出的数据存储到缓存中 // 先将集合转换成json格式的字符串, 使用jackson进行转换 ObjectMapper objectMapper = new ObjectMapper(); userListJson = objectMapper.writeValueAsString(all); redisTemplate.boundValueOps("user.findAll").set(userListJson); System.out.println("=============从数据库中查询============="); } else{ System.out.println("从缓存中查询"); } // 4. 如果存在,将结果返回(测试直接打印就好) System.out.println(userListJson); } }