SpringBoot 2
前言
一、SpringBoot特点
1.1 依赖管理
● 父项目做依赖管理
<!--依赖管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
</parent>
<!--他的父项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.5</version>
</parent>
几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制。
● 开发导入starter场景启动器
<!--web场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1、见到很多 spring-boot-starter-**: 就某种场景启动器
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
官网:https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.5.RELEASE</version>
<scope>compile</scope>
</dependency>
● 无需关注版本号,自动版本仲裁
1、引入依赖默认都可以不写版本
2、引入非版本仲裁的jar,要写版本号。
● 可以修改默认版本号
1、查看spring-boot-dependencies里面规定当前依赖的版本。
2、在当前项目pom.xml里面重写配置
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
1.2 自动配置
● 在我们导入web 场景启动器后,SpringBoot帮我们自动配好Tomcat
○ 引入Tomcat依赖。
○ 配置Tomcat
点击---->spring-boot-starter-web,ctrl + f 搜索tomcat出现如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.4.5</version>
<scope>compile</scope>
</dependency>
web 场景启动器帮我们导入了tomcat依赖。
● 在我们导入web 场景启动器后,SpringBoot自动配好SpringMVC
○ 引入SpringMVC全套组件
○ 自动配好SpringMVC常用组件(功能)
@SpringBootApplication
public class Springboot01HelloWorldApplication {
public static void main(String[] args) {
//1返回一个ioc容器
ConfigurableApplicationContext run = SpringApplication.run(Springboot01HelloWorldApplication.class, args);
//2查看容器组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
在控制台ctrl + f9搜索 DispatcherServlet出现如下:
● 自动配好Web常见功能,如:字符编码问题
○ SpringBoot帮我们配置好了所有web开发的常见场景
在控制台ctrl + f9搜索characterEncodingFilter出现如下:
● 默认的包结构
○ 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
○ 无需以前的包扫描配置
○ 想要改变扫描路径,使用如下注解@SpringBootApplication(scanBasePackages=“com.atguigu”)
■ 或者@ComponentScan 指定扫描路径
● 各种配置拥有默认值
○ 默认配置最终都是映射到某个类上,如:MultipartProperties
○ 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
● 按需加载所有自动配置项
○ 非常多的starter
○ 引入了哪些场景这个场景的自动配置才会开启
○ SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
二、容器功能(组件添加)
2.1 @Configuration 和 @Bean 注解的使用
创建User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private Per per;
public User(int id,String name){
this.id=id;
this.name=name;
}
}
创建Pet类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Per {
private int age;
private String name;
}
传统的基于xml形式像容器添加组件
<bean id="user" class="com.kuang.pojo.User">
<property name="id" value="18"/>
<property name="name" value="洁"/>
</bean>
<bean id="cat" class="com.kuang.pojo.Per">
<property name="age" value="18"/>
<property name="name" value="tomcat"/>
</bean>
使用@Configuration注解实现
/*
1.配置类里面使用Bean注解在方法上给容器注册组件,默认是单例的
2.配置类本身也是个组件
3.proxyBeanMethod:代理bean的方法
Full(proxyBeanMethod = true) user1==user2 true 保证每个@Bean方法调用多少次 返回的组件都只有一个单实例
Lite(proxyBeanMethod = false) user1==user2 false 保证每个@Bean方法调用多少次 返回的组件是新创建的
组件依赖的话必须使用full模式 其他默认lite模式
组件依赖
*/
//告诉springboot这是一个配置类等于以前的配置文件
@Configuration(proxyBeanMethods = true)
public class MyConfig {
/*
*@Configuration(proxyBeanMethods = true)外部无论对配置类中的方法调用多少次都只有一个单实例
*/
@Bean
public User user1(){
User FangJ = new User(18, "FangJ");
//user组件依赖了pet1组件
FangJ.setPer(pet1());
return FangJ;
}
@Bean("tom")//给spring容器中添加组件,以方法名作为组件的的id返回类型就是组件类型 返回的值就是组件在spring容器中的实例
public Per pet1(){
return new Per(10,"tomcat");
}
}
@SpringBootApplication
public class Springboot01HelloWorldApplication {
public static void main(String[] args) {
//1返回一个ioc容器
ConfigurableApplicationContext run = SpringApplication.run(Springboot01HelloWorldApplication.class, args);
//2查看容器组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//3从容其中获取组件
Per tomcat1 = run.getBean("tom", Per.class);
Per tomcat2 = run.getBean("tom", Per.class);
System.out.println(tomcat1 == tomcat2);//true
MyConfig bean = run.getBean(MyConfig.class);
//4输出com.kuang.config.MyConfig$$EnhancerBySpringCGLIB$$96629ca2@3cfdaaf2
System.out.println(bean);
/*
* 如果@Configuration(proxyBeanMethods = true)代理对象调用方法,Springboot总会去检查这个组件是否在容器中有
* 如果有则不会创建实列,保持单实例
*/
User user1 = bean.user1();
User user2 = bean.user1();
System.out.println(user1 == user2);//true
User user01 = run.getBean("user1", User.class);
Per tom = run.getBean("tom", Per.class);
System.out.println("用户的宠物:" + (user01.getPer() == tom));//true
}
2.2 @Controller、@Service、@Repository、@Component
1、@controller:controller控制器层(注入服务)
2、@service :service服务层(注入dao)
3、@repository:dao持久层(实现dao访问)
4、@component:标注一个类为Spring容器的Bean(把普通pojo实例化到spring容器中,相当于配置文件中的< bean id="" class=""/>)
这些注解都能向容器中添加组件。
2.3 @ComponentScan
@ComponentScan 组件扫描,可参考SpringBoot主程序类的包扫描规则。
2.4 @Import
@Import({User.class, DBHelper.class})
给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false)
public class MyConfig {
}
//5 获得组件
String[] beanNamesForType = run.getBeanNamesForType(User.class);
System.out.println("-------------------------------------------");
for(String s:beanNamesForType){
System.out.println(s);
}
DBHelper bean1 = run.getBean(DBHelper.class);
System.out.println(bean1);
2.5 @Conditional
条件装配:满足Conditional指定的条件,则进行组件注入。
@ConditionalOnBean(name = "tom")//容器中有tom组件才加载user1组件
@Bean
public User user1(){
User FangJ = new User(18, "FangJ");
//user组件依赖了pet1组件
FangJ.setPer(pet1());
return FangJ;
}
//@Bean("tom")//给spring容器中添加组件,以方法名作为组件的的id返回类型就是组件类型 返回的值就是组件在spring容器中的实例
public Per pet1(){
return new Per(10,"tomcat");
}
@Configuration(proxyBeanMethods = true)
@ConditionalOnBean(name = "tom")//容器中有tom组件下面的组件才生效
public class MyConfig {
/*
*外部无论对配置类中的方法调用多少次 都只有一个单实例
*/
@Bean
public User user1(){
User FangJ = new User(18, "FangJ");
//user组件依赖了pet1组件
FangJ.setPer(pet1());
return FangJ;
}
@Bean("tom22")//给spring容器中添加组件,以方法名作为组件的的id返回类型就是组件类型 返回的值就是组件在spring容器中的实例
public Per pet1(){
return new Per(10,"tomcat");
}
}
2.6 @ImportResource
项目中的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">
<context:component-scan base-package="com.kuang.config"/>
<bean id="user" class="com.kuang.pojo.User">
<property name="id" value="18"/>
<property name="name" value="jie"/>
</bean>
<bean id="cat" class="com.kuang.pojo.Per">
<property name="age" value="18"/>
<property name="name" value="tomcat"/>
</bean>
</beans>
使用 @ImportResource 注解导入容器
@ImportResource("classpath:bean.xml")
public class MyConfig {
}
判断容器中是否有这两个组件
boolean jie = run.containsBean("jie");
boolean tomcat = run.containsBean("tomcat");
System.out.println("jie: "+jie);
System.out.println("tomcat: "+tomcat);
2.7 配置绑定
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用?
编写实体类
/*
* 只有在容器中的组件才有springboot的强大功能
*/
@Component
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "mycar")
public class Car {
private String brand;
private Integer price;
}
application.properties 文件
#更改项目端口号
server.port=8081
mycar.brand=BYD
mycar.price=100000
controller 层
@Slf4j
@RestController
public class HelloController {
@Autowired
Car car;
@GetMapping("/car")
public Car car(){
log.info("请求进来了-------------------");
return car;
}
}
/*
* @EnableConfigurationProperties(Car.class)
* 1开启Car配置绑定功能
* 2把这个Car这个组件自动注册容器中
*/
@EnableConfigurationProperties(Car.class)
public class MyConfig {
}
@EnableConfigurationProperties(Car.class) 和 @ConfigurationProperties 具有相同效果。