SpringBoot中出现的注解复习
1、@RestController
- @RestController = @Controller + @ResponseBody
- @Controller :表名这个类是一个控制器类。
- @ResponseBody:表示这个方法的返回值直接以指定的格式写入 Http response body 中,而不是解析为跳转路径;格式的转换是通过 HttpMessageConverter 中的方法实现的,因为它是一个接口,因此由其实现类完成转换。如果要求方法返回的是 json 格式数据,而不是跳转页面,可以直接在类上标注 @RestController ,而不是每个方法中标注 @ResponseBody ,简化开发过程
- @Controller 和 @RestController 的区别
- @Controller:在对应的方法上,视图解析器可以解析 return 的 jsp,html页面,并且跳转到相应页面;如果返回json等内容数据,则需要加 @ResponseBody 注解
- @RestController:相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
2、@Configuration
-
功能:将想要的组件添加到容器中
-
标记在类上,告诉springboot这是一个配置类 === 配置文件(spring 中的 spring.xml)
-
使用了@Configuration,则就需要@Bean注解,想要构建出 user 和 pet 对象的话就需要自己将它创建出来;
-
@Bean:给容器中添加组件,以方法名作为组件的id。返回类型为组件类型,返回的值就是组件在容器中的实例
-
在Spring Boot 5.2 之后的 @Configuration 注解多一个属性:proxyBeanMethods,默认为 true(翻译:代理bean的方法)
- true:保证组件的单实例
- 代理就会保持组件的单实例。也就是说,虽然写的MyConfig 是在容器中注册组件的,但是在注册组件之前会在容器中查找有没有该组件。
- 如果有,则取该组件用于保证单实例
- 如果没有再注册一个新的组件
-
Full:(proxyBeanMethods = true):全模式
- 使用代理模式,保证组件的单实例,启动不如fasle快,但是重复利用率高,适合于会重复使用组件的场景
-
lite:(proxyBeanMethods = false):轻量级
- 不是用代理模式,不要保证组件的单实例,启动最快。单每次调用组件都会重新创建一个新的组件,组件的可重复使用率低。适合于需要组件但不会重复使用的场景
3、@Import
- 功能:@Import注解是用来
导入配置类
或者一些需要前置加载的类
;给容器中导入组件,通过无参构造器,而且组件的 id 就是 该类的全类名
- @Import 这个注解,需要写在容器中的组件的类上,可是是配置类,也可以是其他的…
- @Import 支持的三种方式
- 带有@Configuration的配置类,普通类也可以
- ImportSelector 的实现
- ImportBeanDefinitionRegistrar 的实现
@Configuration
@Import(Car.class)
public class MyConfig {}
4、@Conditional
- 条件装配:满足Conditional 指定的条件,则进行组件的注入
- @Conditional 是个父注解,里面包含很多子注解
- 这一系列的注解作用于类或者方法上;
- 注意:这些注解的判断条件为:先检查,在执行
@ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
@ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。
@ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。
@ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。
@ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
@ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression:基于SpEL表达式的条件判断。
@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化
5、@ImportResource
-
@ImportResource:注解用于
导入 spring 的配置文件
;如果不想使用@Bean的方式,就可以使用@ImportResource导入外部配置文件 -
以前写的 springmvc.xml 在SpringBoot 里面并没有,我们自己编写的配置文件也不能自动识别;这里就可以使用 @ImportResourse
标注在一个配置类
上让 Spring 的配置文件生效
@Configuration
@ImportResource("classpath:spring.xml") //标记在配置类之上
public class MyConfig {}
6、@ConfigurationProperties
- @ConfigurationProperties 注解用于
自动配置绑定
,可以将 application.properties 配置在的值注入到 bean 对象中;
6.1、场景一
- 使用
@ConfigurationProperties
和@Component
注解到 bean 定义类上,这里 @Component 代指同一类实例化 Bean 的注解;
@Component
@ConfigurationProperties(prefix="user1")
public class User{
private String name;
//省略getter / setter 方法
}
- 对应的 application . properties 配置文件内容:
user1.name=Tom
- 在此种场景下,当Bean被实例化时,@ConfigurationProperties 会将对应前缀的后面的属性与 Bean 对象的属性匹配。符合条件就赋值
6.2、场景二
- 使用
@ConfigurationProperties
和@Bean
注解在配置类的Bean定义方法上,
@Configuration
public class DataSourceConfig{
@Bean(name="tom")
@ConfigurationProperties(prefix="spring.data.tomSource")
public DataSource getTomSource(){
return DataSourceBuilder.create().build();
}
}
-
这里便是将前缀为 "spring.data.tomSource"的属性,赋值给 DataSource 对应的属性值;
-
对应的 application . properties 配置文件内容:
spring.data.tomSource="NEW"
6.3、场景三(重要)
- 使用
@ConfigurationProperties
注解到普通类,然后再通过@EnableConfigurationProperties
定义为 Bean
@ConfigurationProperties(prefix = "user1")
public class User{
private String name;
//省略getter/setter方法
}
- 这里的User对象并没有使用 @Component 相关注解
- 而该User类对应的使用形式如下:(在配置类上都行)
@SpringBootApplication
@EnableConfigurationProperties({User.class})
public class Application{
public static void main(String[] args) throws Exception{
SpringApplication.run(Application.class,args);
}
}
- 上述代码中,通过@EnableConfigurationProperties对 User 进行实例化时,便会使用到 @ConfigurationProperties 的功能,对属性进行匹配赋值;
- @EnableConfigurationProperties 的
作用
:
- 1:开启指定javaBean的属性配置功能
- 2:将指定的javaBean加入到容器中
- 但是加入到容器中的id:不是类名的首字母小写;而是:prefix属性+ - +类的全包名
- 比如:
mycar-com.wang.boot.pojo.Car
7、@ComponentScan
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdNPLOuD-1691736783679)(C:\Users\ASUS\Desktop\java\7_springboot核心技术\image\1677031448290.png)]
-
@ComponentScan 用于
类或接口
上主要是指定扫描路径
,Spring 会把指定路径下带有指定注解的类
自动装配到 bean容器里。会被自动装配的注解包括:@Controller
、@Service
、@Component
、@Repository
等等。与 CompoentScan 注解相对应的 XML 配置就是< context:component-scan/> ,根据指定的配置自动扫描 package ,将符合条件的组件加入到 IOC 容器中; -
XML配置方式如下
<context:component-scan
base-package="com.example.test" use-default-filters="false">
<context:exclude-filter type="custom"
expression="com.example.test.filter.MtyTypeFilter" />
</context:component-scan>
- @ComponentScan 注解属性:
- basePackages 和 value :指定要扫描的路径(package),如果为空则以@CompentScan 注解的类所在的包为基本的扫描路径
8、@SpringBootConfiguration
- SpringBoot 中的 @SpringBootConfiguration 注释是一个类级别的注释,它指示此类提供了应用程序配置;
- 当我们使用 @SpringBootConfiguration 标记一个类时,这意味着该类提供了 @Bean 定义的方法(相当于就是 @Configuration 这个注释)。Spring 容器处理配置类以为我们的应用实例化和配置 bean ;
9、@EnableAutoConfiguration
9.1、作用
- 简单点来说就是 Spring Boot根据依赖中的 jar 包,自动选择实例化某些配置,配置类必须有 @Configuration 注解
- 说白了,还是实例化对象,只是实例化的是依赖包中的类
- 另外,我们也可以按照自动装配的规范自己定义装配的类。
9.2、@EnableAutoConfiguration和 @Configuration 的区别
- @Configuration
- 表示作用的类是个配置类,我们平时也会写配置类;
- 比如我们系统中的DataSourceConfig类,但是由于这个类是在Starter对应的子目录下,会自动加载,所以@EnableAutoConfiguration就作用不到了
- @EnableAutoConfiguration
- 是一个加载 Starter目录包之外的需要 Spring 自动生成bean对象(是否需要的依据是 "META-INF/spring.factories"中org.springframework.boot.autoconfiguration.EnableAutoConfiguration 后面是有能找到哪个bean)的带有 @Configuration 注释的类。一般就是对各种引入的 spring-boot-starter 依赖包指定的(spring.factories)类进行实例化;
9.3、整体流程
- 我们启动类中会加上 @SpringBootApplication
- @SpringBootApplication 包含了 @EnableAutoConfiguration,
告知应用启动的时候需要扫描依赖包中需要实例化的类
- SpringBoot启动的时候会去扫描 META/spring.factories ,查看具体是哪些类需要实例化
- 扫描哪些需要实例化的类,看下是否有 @Configuration 注解,如果有,则实例化
- 实例化的时候可能需要一些配置属性,一般这些类都会加上 @EnableConfigurationProperties(RocketMQProperties.class)
- RocketMQProperties会将属性映射为 bean 类
10、@AutoConfigurationPackage
- @AutoConfigurationPackage是在springboot启动类注解@SpringBootApplication下的@EnableAutoConfiguration下。@AutoConfigurationPackage作用是指定springboot扫描包,默认就是扫描启动类同包下的类
- 扫描包就是指的这个包下使用@Service、@Controller…等注解的会被存入Spring容器。
- 可以通过@AutoConfigurationPackage来附加其他路径,然后springboot同样会进行扫描
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SRxcMaRF-1691736783680)(C:\Users\ASUS\Desktop\java\7_springboot核心技术\image\1677136211072.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MywmmHqO-1691736783681)(C:\Users\ASUS\Desktop\java\7_springboot核心技术\image\1677136339654.png)]
- Register 是 AutoConfigurationPackages 当中的一个内部类,注意这个类实现了
ImportBeanDefinitonRegistrar
接口。通过@Import 注入对象一共有四种方式,通过ImportBeanDefinitonRegistrar 接口的实现类注入就是其中方式之一
11、@Import(AutoConfigurationImportSeletor.class)
- 它是利用 AutoConfigurationImportSeletor 机制再来给容器中批量,导入哪些东西;
- AutoConfigurationImportSeletor 有一个方法
selectImports()
,就是我们到底要给容器中导哪些(String[ ])这个数组(String[ ])里面要导哪些就导哪些。然后所有的东西都是调用getAutoConfigurationEntry()
方法得到的,然后autoConfigurationEntry
最终得到所有的配置(getConfigurations
)转成String 数组(StringUtils.toStringArray()
)返回出去- 所以核心就在 getAutoConfigurationEntry()方法上
selectImports ---> getAutoConfigurationEntry() ---> getCandidateConfigurations()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIzV64ee-1691736783682)(C:\Users\ASUS\Desktop\java\7_springboot核心技术\image\1677143452887.png)]
- 虽然它一股脑的加载了所有,但是最终得益于springboot的按需加载的这个注解,我们说的条件装配,很多东西并不能完全开启,所以说这就是我们springboot自动配置的核心:启动加载所有写死的场景自动配置(在这个spring-boot-autoconfigure-2.5.6.jar/META-INF/spring.factories)但是按照最终按照条件装配规则,最终会按需配置
12、xxxMapping
- 以GetMapping为例子
- produces:它的作用是指定返回值类型和返回值编码;这里是返回 json,和utf-8编码
@GetMapping(value = "/generalInfoForImageUrl", produces = "application/json;charset=utf-8")
public ResultBean generalInfoForImageUrl(@RequestParam(value = "url") String url) {}
最终会按需配置
12、xxxMapping
- 以GetMapping为例子
- produces:它的作用是指定返回值类型和返回值编码;这里是返回 json,和utf-8编码
@GetMapping(value = "/generalInfoForImageUrl", produces = "application/json;charset=utf-8")
public ResultBean generalInfoForImageUrl(@RequestParam(value = "url") String url) {}