天天看点

2021年5月27日——SpringBoot2基础入门SpringBoot2——基础入门

SpringBoot2——基础入门

一、Spring 与 SpringBoot

1. SpringBoot优缺点

1.1 优点

  • 创建独立Spring应用
  • 内嵌web服务器
  • 自动starter依赖,简化构建配置
  • 自动配置Spring以及第三方功能
  • 提供生产级别的监控、健康检查及外部化配置
  • 无代码生成、无需编写XML

1.2 缺点

  • 人称版本帝,迭代快,需要时刻关注变化
  • 封装太深,内部原理复杂,不容易精通

2. 如何学习

官方参考文档:Spring Boot Reference Documentation

版本新特性:Home · spring-projects/spring-boot Wiki · GitHub

二、SpringBoot2快速入门

1. 环境要求

  • Java 8 & 兼容 java14 .
  • Maven 3.3+
  • idea 2019.1.2

2. 创建Hello工程

2.1 工程文件

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>net.tiejiankudan</groupId>
    <artifactId>part01_quicklyStart</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 貌似不写也不影响打包 -->
    <packaging>jar</packaging>

    <!-- 父工程作了很多版本控制(点开他的父工程就可以看到了) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        	<!-- 打包必备 -->    
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
           
  • 主程序:net.tiejiankudan.MainApplication
// 组合注解,默认扫描当前类所在的包及其子包,也可以通过 scanBasePackages 改变扫描范围
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
      SpringApplication.run(MainApplication.class, args);
    }
}
           
  • controller:net.tiejiankudan.controller.HelloController
// 相当于 @ResponseBody + @Controller 
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot 2";
    }
}
           
  • 因为集成tomcat,所以修改配置文件就可以配置tomca了
  • application.properties

2.2 测试

运行 net.tiejiankudan.MainApplication 即可。

2.3 简化部署

  • 打成jar包,使用mvn: package,千万不要使用Plugins下jar打包,那个没用
  • 运行jar包
java -jar 包路径
           

三、了解自动配置原理

1. SpringBoot特点

  • 父项目做依赖版本管理
    • spring-boot-starter-parent =》spring-boot-dependencies
    • 想要改版本的话,找到spring-boot-dependencies里定义好的标签名,在自己的项目配置里重写即可
      <properties>
      	<mysql.version>5.1.43</mysql.version>
      </properties>
                 
  • starter场景启动器自动导入所需jar包还做好了自动配置
    • spring-boot-starter-* 官方启动器
    • *-spring-boot-starter 第三方启动器
    • 启动器大全:Using Spring Boot
    • 各种配置拥有默认值
      • 默认配置最终都是映射到某个类上,如:MultipartProperties
      • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
    • 按需加载所有自动配置项
      • 引入了哪些场景这个场景的自动配置才会开启
      • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

2. 容器功能

2.1 组件添加

2.1.1 配置类

@Configuration

  • 声明一个配置类,配置类也会加入到IOC容器
  • Full模式与Lite模式

net.tiejiankudan.config.Myconfig

// Full(proxyBeanMethods = true)
// Lite(proxyBeanMethods = false)
@Configuration(proxyBeanMethods = true)
public class Myconfig {
    @Bean
    public User user() {
        return new User();
    }
}
           

net.tiejiankudan.MainApplication

public class MainApplication {
    public static void main(String[] args) {
        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2.查看容器中的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        // 3.从容器中获得组件:不管是Lite还是Full都是同一个
        User user = run.getBean("user", User.class);
        User user2 = run.getBean("user", User.class);
        System.out.println("user1: " + user);
        System.out.println("user2: " + user2);

        // 通过配置组件创建对象: Lite不是同一个,Full是同一个
        Myconfig config = run.getBean(Myconfig.class);
        User user3 = config.user();
        User user4 = config.user();
        System.out.println(user3);
        System.out.println(user4);

        
        /************************************************************
         * 结论:
         *      proxyBeanMethods = true 时,
         *			调用创建Bean的方法时会检测容器中是否已经存在Bean了,
         *			存在则直接用容器中的Bean
         *      proxyBeanMethods = false 时,
         *			则不会检测,直接new出新的Bean,比true速度快,
         *			故称之为Lite
         ************************************************************/
    }
}
           
2.1.2 添加Bean

@Bean、@Component、@Controller、@Service、@Repository

2.1.3 组件扫描

@ComponentScan

2.1.4 导入配置

@Import({Object1.class, Object2.class}):

  • 就是给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
2.1.5 条件装配

@Conditional:

  • 满足Conditional指定的条件,则进行组件注入

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class Myconfig {

}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Object tom = run.getBean("tom");
        Myconfig myconfig = run.getBean(Myconfig.class);
        System.out.println(tom);
        System.out.println(myconfig);
        
        
        /************************************************************
         * 结论:
         *      @ConditionalOnBean(name = "tom")生效时:
         *			容器中有叫tom的Bean时,Myconfig才被加入到容器中
         *      @ConditionalOnMissingBean(name = "tom")生效时:
         *			容器中没有叫tom的Bean时,Myconfig才被加入到容器中
         		利用这个注解Spring-boot才能做到按需加载配置类进入容器
         ************************************************************/
    }
}
           

2.2、原生配置文件引入

2.2.1 引入配置文件

@ImportResource:

  • 引入SSM时期一直用的xml配置文件,不过一定要注意配置文件名不要命名成application.xml,这样会报错。

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="tom" class="net.tiejiankudan.domain.User"></bean>
<bean id="jerry" class="net.tiejiankudan.domain.User"></bean>
</beans>
           

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
@ImportResource("classpath:bean.xml")
public class Myconfig {

}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Object tom = run.getBean("tom");
        Object jerry = run.getBean("jerry");
        System.out.println(tom);
        System.out.println(jerry);
        
        /************************************************************
         * 结果:
         *      [email protected]
		 *		[email protected]
         ************************************************************/
    }
}
           
2.2.2 配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用。

声明成属性类后,会出现个提示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NFHZQQ1-1622093046923)(D:\Document\Note\picture\002.jpg)]

不要让他出现的话可以添加依赖:

<dependency>
	<groupId> org.springframework.boot </groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<!--不传递依赖-->
	<optional>true</optional>
</dependency>
           

方式一:@Component + @ConfigurationProperties(prefix = “xxx”)

net.tiejiankudan.property.CarProperties

// 加入到IOC容器中就可以自动配置属性了,代替了之前的@PropertySource() + @Value 的做法
@Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
           

application.properties

server.port=9000
mycar.brand=wulinghonguang
mycar.price=23333
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        CarProperties carProperties = run.getBean(CarProperties.class);
        System.out.println(carProperties);
        
        
        /************************************************************
         * 结果:
         *      Car{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

方式二:@EnableConfigurationProperties + @ConfigurationProperties(prefix = “xxx”)

net.tiejiankudan.property.CarProperties

// 注意 @Component 是被注释了的
// @Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
           

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
// 下面的注解又把配置类加入到容器中
@EnableConfigurationProperties(CarProperties.class)
public class Myconfig {
    @Bean
    public Car car(CarProperties carProperties) {
        Car car = new Car();
        car.setBrand(carProperties.getBrand());
        car.setPrice(carProperties.getPrice());
        return car;
    }
}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        CarProperties carProperties = run.getBean(CarProperties.class);
        Car car = run.getBean(Car.class);
        System.out.println("carProperties: " + carProperties);
        System.out.println("car" + car);
        
        
        /************************************************************
         * 结果:
         *     carProperties: Car{brand='wulinghonguang', price=23333}
		 *	   carCar{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

方式二: @ConfigurationProperties(prefix = “xxx”)

  • 思考:属性类在容器中 =》容器自动注入属性
  • 那么:任何对象,只要在容器中就可以自动注入属性,那还要什么属性类(●’◡’●)

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
public class Myconfig {
    @Bean
    @ConfigurationProperties(prefix = "mycar")
    public Car car() {
        return new Car();
    }
}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Car car = run.getBean(Car.class);
        System.out.println("car" + car);
        
        
        /************************************************************
         * 结果:
		 *	   carCar{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

3. 自动配置原理

太复杂了,我暂时先跳过╮(╯-╰)╭

4. 开发小技巧

4.1 Lombok

简化JavaBean开发

  • idea中搜索安装lombok插件
  • 在pom文件中引入依赖

pom.xml

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
</dependency>
           
  • 在类上标明注解:
    • @NoArgsConstructor:自动加入无参构造
    • @AllArgsConstructor:自动加入全参构造
    • @Data:自动get/set方法
    • @ToString:自动加入tostring()方法
    • @EqualsAndHashCode:自动重写equals和HashCode方法
    • @Slf4j:标注后该类里就有了一个静态属性log

4.2 dev-tools

pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
	<optional>true</optional>
</dependency>
           

项目或者页面修改以后:Ctrl+F9重新构建项目。参考:Spring DevTools

4.3 Spring Initializr

项目创建的时候直接创建spring-boot项目可加速构建项目