2.第一个SpringBoot程序
2.1环境配置
我们将学习如何快速的创建一个Spring Boot应用,并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。
我的环境准备:
java version “1.8.0_181” Maven-3.6.1 SpringBoot 2.x 最新版 开发工具:
IDEA
2.2创建基础项目说明
Spring官方提供了非常方便的工具让我们快速构建应用,IDEA也集成了这个网站
Spring Initializr:https://start.spring.io/
2.3.1项目创建方式一
使用Spring Initializr 的 Web页面创建项目
2、填写项目信息
3、点击”Generate Project“按钮生成项目;下载此项目
4、解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。
5、如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。
2.3.2项目结构分析
使用 IDEA 直接创建项目
1、创建一个新项目
2、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现
3、填写项目信息
4、选择初始化的组件(初学勾选 Web 即可)
5、填写项目路径
6、等待项目构建成功
2.3.3项目结构分析
通过上面步骤完成了基础项目的创建。就会自动生成以下文件。
1、程序的主启动类(程序的主入口)
2、一个 application.properties 配置文件(SpringBoot的核心配置文件
3、一个 测试类
4、一个 pom.xml
pom.xml文件分析
<!-- 父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- web场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- 剔除依赖 -->
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
编写一个http接口
1、在主程序的目录下,新建一个controller包,一定要在同级目录下,否则识别不了
2、在包中新建一个HelloController类
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World";
}
}
3、编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了 Tomcat 访问的端口号!
更改端口号:在application资源文件中配置
server.port = xxxx
2.3SpringBoot特点
2.3.1依赖管理
- 父项目做依赖管理
依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
它的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.0</version>
</parent>
spring-boot-dependencies 几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
- 开发导入starter场景启动器
1、见到很多 spring-boot-starter-* : *就是某种场合环境
2、只要引入starter,这个场景环境的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
4、见到 *-spring-boot-starter:第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
- 无需关注版本号,自动版本仲裁
1、引入依赖默认都可以不写版本
2、导入非版本的jar,要写版本号
- 可以修改默认版本号
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key
2、在当前项目里面重写配置
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
2.3.2自动配置
-
自动配置好Tomcat
-
引入Tomcat依赖
-
配置Tomcat
-
该jar在spring-boot-starter-web中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
自动配置好SpringMVC
-
引入SpringMVC全套组件
-
自动配置好SpringMVC常见组件(功能)
-
自动配置好Web常见功能,如:字符编码问题
-
SpringBoot帮我们配置好了所以web开发的常见环境(spring环境)
-
默认包的结构
-
主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来、
-
无需以前的包扫描配置(包扫描是用来识别 @Service、@Controller这些注释,然后在IOC容器中生成bean)
-
想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.guo”)或者或者@ComponentScan 指定扫描路径
-
@SpringBootApplication 注释
-
@SpringBootApplication 等同于 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan("com.guo.boot")
-
各种配置拥有默认值
-
默认配置最终都是映射到某个类上
-
配置文件的值最终会绑定在每个类上,这个类会在容器中创建对象
-
按需加载所有自动配置项
-
非常多的starter
-
引入了那些场景,这个场景的自动配置才会打开
-
SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
-
-
2.4容器功能
2.4.1组件添加
1.@Configuration 给类添加这个注解后,相当于原来的向bean注入的bean.xml(就是在applicationContext.xml中写来注入类)
-
基本使用
- Full模式(全配置)和Lite模式(轻量级配置)
代码实例:
#############################Configuration使用示例######################################################
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
* Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
* 组件依赖必须使用Full模式默认,proxyBeanMethods = true。
其他默认是否Lite模式:proxyBeanMethods = flase
*
*
*
*/
@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
################################@Configuration测试代码如下########################################
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
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、从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class);
Pet tom02 = run.getBean("tom", Pet.class);
System.out.println("组件:"+(tom01 == tom02));//true
//4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
MyConfig bean = run.getBean(MyConfig.class);
System.out.println(bean);//com.kuang.config.MyConfig$$EnhancerBySpringCGLIB$$874f5927@1235151c
//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
//保持组件单实例
User user = bean.user01();
User user1 = bean.user01();
System.out.println(user == user1);//true
User user01 = run.getBean("user01", User.class);
Pet tom = run.getBean("tom", Pet.class);
System.out.println("用户的宠物:"+(user01.getPet() == tom));//用户的宠物:true
}
}
2、@Bean、@Component、@Controller、@Service、@Repository
3、@ComponentScan、@Import
@Import会给容器中自动创建这两个类型的组件
* 4、@Import({User.class, DBHelper.class})
* 给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
*/
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}
4、@Conditional(条件装配注解)
条件装配:当满足Conditional指定的条件,则进行组件注入
先看结论:当这个注释配置在类上时,只有这个类注入了响应名称的组件才会生成相应的实体,
当配置部分方法时候,只有相应的被注入才可以生成实体,否则就不生效
=====================测试条件装配==========================
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom22")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
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);
}
boolean tom = run.containsBean("tom");
System.out.println("容器中Tom组件:"+tom);
boolean user01 = run.containsBean("user01");
System.out.println("容器中user01组件:"+user01);
boolean tom22 = run.containsBean("tom22");
System.out.println("容器中tom22组件:"+tom22);
}
2.4.2原生配置文件引入
@ImportResource
======================beans.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="haha" class="com.atguigu.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
<bean id="hehe" class="com.atguigu.boot.bean.Pet">
<property name="name" value="tomcat"></property>
</bean>
</beans>
/**
* Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
* 如果想让Spring的配置文件生效,加载到Spring 容器中来;
* 使用@ImportResource注解,将其标注在一个配置类上(此处配置在启动类)
*/
@SpringBootApplication
@ImportResource(locations = {"classpath:beans.xml"})
public class BootApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(BootApplication.class,args);
}
}
2.4.3配置绑定
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;
public class getProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties pps = new Properties();
pps.load(new FileInputStream("a.properties"));
Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
while(enum1.hasMoreElements()) {
String strKey = (String) enum1.nextElement();
String strValue = pps.getProperty(strKey);
System.out.println(strKey + "=" + strValue);
//封装到JavaBean。
}
}
}
1.@ConfigurationProperties
注意想要使用这个注解必须声明组件注解@Component
@ConfigurationProperties使用非常简单,就是自动为属性注入配置值。
/**
* 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
*/
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
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.property文件:
mycar.price = 100000
mycar.brand = BYD
更通用的方式是与@Configuration使用在配置类上:
@Configuration
@ConfigurationProperties(prefix = "db.mysql.stock")
public class DBConfig {
}
2.@EnableConfigurationProperties = @Component + @ConfigurationProperties
@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
}