一、注解
1、@SpringBootApplication
这个注解是Spring Boot最核心的注解,用在 Spring Boot的主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。实际上这个注解是@Configuration,@EnableAutoConfiguration,@ComponentScan三个注解的组合。由于这些注解一般都是一起使用,所以Spring Boot提供了一个统一的注解@SpringBootApplication。
2、@Controller
在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面
若返回json等内容到页面,则需要再加上@ResponseBody注解
3、@ResponseBody
表示该方法的返回结果直接写入HTTP response body中。
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
4、@RestController
用于标注控制层组件(如struts中的action),表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器;它是@Controller和@ResponseBody的合集
5、@ComponentScan
组件扫描。让spring Boot扫描到Configuration类并把它加入到程序上下文。
@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中。
6、@Repository
@Repository 是 Spring 的注解,用于声明一个 Bean。@Repository单独使用没用。可以这样理解,注解放在接口上本来就没有意义,spring中在mapper接口上写一个@Repository注解,只是为了标识,要想真正是这个接口被扫描,必须使用@MapperScannerConfigurer
eg:
<!-- 配置 Mapper 扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shenlei.mapper"/>
</bean>
这段配置会扫描com.shenlei.mapper包下所有的接口,然后创建各自的动态代理类。
7、@Mapper
@Mapper是mybatis自身带的注解。在spring程序中,mybatis需要找到对应的mapper,在编译时生成动态代理类,与数据库进行交互,这时需要用到@Mapper注解
但是有时候当我们有很多mapper接口时,就需要写很多@Mappe注解,这样很麻烦,有一种简便的配置化方法便是在启动类上使用@MapperScan注解,这样可以自动扫描包路径下所有的mapper接口,从而不用再在接口上添加任何注解。
相同点:
@Mapper和@Repository都是作用在dao层接口,使得其生成代理对象bean,交给spring 容器管理
不同点:
1、@Mapper不需要配置扫描地址,可以单独使用,如果有多个mapper文件的话,可以在项目启动类中加入@MapperScan(“mapper文件所在包”)
2、@Repository不可以单独使用,否则会报错误,要想用,必须配置扫描地址(@MapperScannerConfigurer)
8、@Service
一般用于修饰service层的组件
9、@Component
泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
10、@Bean
相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
详细介绍:https://blog.csdn.net/weixin_42140261/article/details/104864333
11、@AutoWired
byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
当加上(required=false)时,就算找不到bean也不报错。
12、@Qualifier
当有多个同一类型的Bean时,可以用@Qualifier("name")来指定。与@Autowired配合使用
13、@Resource(name=“name”,type=“type”)
没有括号内内容的话,默认byName。与@Autowired干类似的事。
14、@PathVariable
路径变量。参数与大括号里的名字一样要相同
例如:
@GetMapping("sendMessage/{message}")
public void sendMessage(@PathVariable String message){
// do others
}
15、@Param
mybatis框架中给SQL语句中的参数赋值的
eg:
mapper中的方法:
public User selectUser(@Param("userName") String name,@Param("password") String pwd);
映射到xml中的<select>标签:
<select id="selectUser" resultMap="User">
select * from user where user_name = #{userName} and user_password=#{password}
</select>
其中where user_name = #{userName} and user_password = #{password}中的userName和password都是从注解@Param()里面取出来的,取出来的值就是方法中形式参数 String name 和 String pwd的值。
16、@RequestParam
用于将指定的请求参数赋值给方法中的形参
有三个属性:
(1)value:请求参数名(必须配置)
(2)required:是否必需,默认为 true,即 请求中必须包含该参数,如果没有包含,将会抛出异常(可选配置)
(3)defaultValue:默认值,如果设置了该值,required 将自动设为 false,无论你是否配置了required,配置了什么值,都是 false(可选配置)
举例:
1.为演示效果,首先需要创建一个测试控制类,然后创建一个测试方法,如图所示,方法里添加一个参数,此时方法参数没有添加注解
2.通过idea工具启动web项目,然后通过浏览器访问测试效果,不带参数则获取的参数为null,但页面可以正常显示,请求可以正常的执行。
带上参数之后,参数可以正常的获取并打印出来了
3.下面来对比下添加注解的效果,但只是添加@RequestParam,没有带任何的注解设置参数。
4.再次通过浏览器访问查看效果,此时带上userName参数页面可以正常显示并打印出结果值,但如图所示,不带参数的时候,页面报错,返回400,并提示userName不存在
5.当然这样的限制是可以选择的,@RequestParam里添加required=false来关闭必须参数的限制,这样就和第一种不带注解的效果一样了
6.@RequestParam还可以在参数为空的情况下,为我们设置一个参数的默认值,如图所示,可以看出来,没有参数的情况下,获取到的就是默认值
7.默认参数的key名称是方法里的参数名称,但通过@RequestParam可以自定义另外一个,因为在某些条件下,方法名称固定下来不可以修改了,但请求的参数又需要通过另外一个参数key名称来传递,这样就可以通过这样的方式来实现
17、@PostConstruct
该注解是Java jdk提供的注解,而不是Spring框架提供的, JavaEE5引入了@PostConstruct和@PreDestroy两个作用于Servlet生命周期的注解,实现Bean初始化之前和销毁之前的自定义操作。
该注解的方法在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的初始化方法)
18、@Configuration
Configuration注释类表明其主要目的是作为bean定义的源;@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系
19、@Import
@Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件、默认组件的名字就是 全类名
20、@Conditional
条件装配:满足Conditional指定的条件,则进行组件注入
用@ConditionalOnMissingBean举例说明
@ConditionalOnMissingBean(name = "tom")//没有tom名字的Bean时,MyConfig类的Bean 才能生效。
21、@ImportResource
@ImportResource注解用于导入Spring的配置文件,让配置文件里面的内容生效
例如:
@ImportResource(locations = "classpath:applicationContext.xml")
@SpringBootApplication
public class Project50RabbitmqFinalApplication {
public static void main(String[] args) {
SpringApplication.run(Project50RabbitmqFinalApplication.class, args);
}
}
22、@ConfigurationProperties
Spring Boot提供了基于类型安全的配置方式,通过@ConfigurationProperties将properties属性和一个Bean关联,从而实现类型安全的配置。
第一种方式:
1.
@Component
@ConfigurationProperties(prefix = "book01")
public class Book {
private String name;
private String author;
private int age;
//get.. set..
}
2.
application.properties文件下配置
book01.name="java实战"
book01.author="李四"
book01.age=12
第二种方式:
1.
@EnableConfigurationProperties({com.example.pojo.Book.class})
@Configuration
public class Myconfig {
@Autowired
private Book book;
.....
}
2.
@ConfigurationProperties(prefix = "book02")
public class Book {
private String name;
private String author;
private int age;
//get.. set..
}
3.
application.properties文件下配置
book02.name="java实战"
book02.author="李四"
book02.age=12
二、插件
1、快速打包
Spring Boot 在 Maven 是通过引入 spring-boot-maven-plugin 插件来构建可执行 Jar 包的
eg:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在IDEA的Maven插件上点击运行 clean 、package,把helloworld工程项目的打包成jar包,
打包好的jar包被生成在helloworld工程项目的target文件夹内。
用cmd运行java -jar boot-01-helloworld-1.0-SNAPSHOT.jar,既可以运行helloworld工程项目。
将jar包直接在目标服务器执行即可。
三、依赖管理原理
1、父项目做依赖管理
springboot项目依赖于其父项目,如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
<!-- lookup parent from repository:指定了relativePath,
但值是空的,设定一个空值将始终从仓库中获取,不从本地路径获取. -->
<relativePath/>
</parent>
此项目又依赖于
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.1.6</version>
</parent>
其内部规定了一系列的版本号,如下:
<properties>
<activemq.version>5.18.3</activemq.version>
<angus-mail.version>1.1.0</angus-mail.version>
<artemis.version>2.28.0</artemis.version>
<aspectj.version>1.9.20.1</aspectj.version>
<assertj.version>3.24.2</assertj.version>
<awaitility.version>4.2.0</awaitility.version>
<brave.version>5.15.1</brave.version>
.......
</properties>
它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
2、自动版本仲裁
引入依赖默认都可以不写版本
引入非版本仲裁的jar,要写版本号。
3、修改默认版本号
1. 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2. 在当前项目里面重写配置,如下面的代码。
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
4、starter场景启动器
starter场景启动器:spring-boot-starter-* (*表示某种场景)
例如:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
里面自动导入了这个场景的所有常规需要的依赖
eg:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.1.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>3.1.6</version>
<scope>compile</scope>
</dependency>
.......
</dependencies>
而所有场景启动器最底层的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.1.6</version>
<scope>compile</scope>
</dependency>
*-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
四、自动配置原理
1、默认的包结构
主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
无需以前的包扫描配置
改变扫描路径:
①:@SpringBootApplication(scanBasePackages="com.lun")
②:@ComponentScan 指定扫描路径----》因为
@SpringBootApplication 等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.lun")
2、各种配置拥有默认值
配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
例如:
spring.rabbitmq.host=122.51.109.18
spring.rabbitmq.username=admin
spring.rabbitmq.password=hx801219
spring.rabbitmq.port=5672
3、按需加载所有自动配置项
非常多的starter
引入了哪些场景这个场景的自动配置才会开启
SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
例如:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
进入里面,得到
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.1.6</version>
<scope>compile</scope>
</dependency>
再进入里面,得到
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.1.6</version>
<scope>compile</scope>
</dependency>
对应到目录里面如下:
4.springboot自动配置原理详解
我们都知道SpringBoot启动的时候先加载主程序类(主程序类也叫主配置类),主程序类被@SpringBootApplication标注,查看此注解源码我们发现,此注解是由:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.laizhenghua.boot_helloworld")
这三个注解合成,如下所示:
// @SpringBootApplication // 标注SpringBoot应用
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.laizhenghua.boot_helloworld")
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
4.1、@SpringBootConfiguration
点进去@SpringBootConfiguration,发现被@Configuration标注,这也说明:主程序类也是一个配置类。
4.2、@ComponentScan
前面已经介绍过了,是一个Spring的注解,用来指定包的扫描范围!
加了包扫描@ComponentScan注解后,只要标注了@Controller、@Service、@Repository、@Component注解中的任何一个,其组件都会被自动扫描,加入到容器中。
例如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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解支持-->
<context:annotation-config/>
<!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.howie"/>
</beans>
4.3、@EnableAutoConfiguration – 核心注解
SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration。此注解也是SpringBoot自动配置的核心注解,并且也是一个合成注解!
// 由以下两个注解合成
...
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
4.3.1、@AutoConfigurationPackage
自动配置包?指定了默认的包规则!
点进去此注解:
...
@Import(AutoConfigurationPackages.Registrar.class) // 给容器中导入一个组件
public @interface AutoConfigurationPackage {
...
}
然后我们可以看到其中的一段代码:
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 进行批量注册
AutoConfigurationPackages.register(registry, (String[])(new PackageImports(metadata)).getPackageNames().toArray(new String[0]));
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImports(metadata));
}
}
我们可以看到:
利用Registrar给容器中导入一系列组件
将指定的一个包下的所有组件导入进来?MainApplication 所在包下。
这里就是获取了主配置类的信息,利用Registrar给容器中导入了主配置类子包中声明的所有组件!
4.3.2、@Import(AutoConfigurationImportSelector.class)
给容器中导入了类型为AutoConfigurationImportSelector的组件,然后我们查看此类到底做了些什么?
1.利用getAutoConfigurationEntry(annotationMetadata)方法,给容器中批量导入一些组件。
2.调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes),获取到所有需要导入到容器中的配置类。
3.利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader),得到所有的组件,我们点进去可以看到:
4.从META-INF/spring.factories位置来加载一个文件。
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.9.RELEASE.jar包里面也有META-INF/spring.factories,如下:
小结:
1.通过注解@AutoConfigurationPackage里面合成的注解,加载主配置类下子包中声明的所有组件。例如:使用@Controller、@Service、@Bean、@Mapper、@Configuration等注解标注的类或方法,将类或方法(变成了组件)注册到容器中。
2.通过注解@Import(AutoConfigurationImportSelector.class)将所有META-INF/spring.factories位置的文件中写死的全类名组件(配置类)都注入容器中。
3.需要注意的是不一定每一个配置类里或类里面的声明的组件都有用,如果全部都加载了,对内存对资源是一种极大的浪费,所以在SpringBoot里有了按需开启自动配置项 !
4.3.3、按需开启自动配置项
虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。
4.4、自动配置流程
1.SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
2.每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里xxxProperties和全局配置文件进行了绑定
3.生效的配置类就会给容器中装配很多组件
4.只要容器中有这些组件,相当于这些功能就有了
5.只要用户有自己配置的,就以用户的优先
定制化配置:
1.开发者直接自己@Bean替换底层的组件
2.开发者去看这个组件是获取的配置文件什么值就去修改
器中。
2.通过注解@Import(AutoConfigurationImportSelector.class)将所有META-INF/spring.factories位置的文件中写死的全类名组件(配置类)都注入容器中。
3.需要注意的是不一定每一个配置类里或类里面的声明的组件都有用,如果全部都加载了,对内存对资源是一种极大的浪费,所以在SpringBoot里有了按需开启自动配置项 !
#### 4.3.3、按需开启自动配置项
```tex
虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。
4.4、自动配置流程
1.SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
2.每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里xxxProperties和全局配置文件进行了绑定
3.生效的配置类就会给容器中装配很多组件
4.只要容器中有这些组件,相当于这些功能就有了
5.只要用户有自己配置的,就以用户的优先
定制化配置:
1.开发者直接自己@Bean替换底层的组件
2.开发者去看这个组件是获取的配置文件什么值就去修改