Spring Boot 注解
Spring
@Component
- @Component注解表明⼀个类会作为组件类,并告知Spring要为这个类创建bean
- @Component (@Controller、@Service、@Repository)通常是通过类路径扫描来⾃动侦测以及⾃动装配到Spring容器中。
@Bean
- @Bean注解告诉Spring这个⽅法将会返回⼀个对象,这个对象要注册为Spring应⽤上下⽂中的bean。
- 通常⽅法体中包含了最终产⽣bean实例的逻辑,并且实例名就是⽅法名。
- @Bean则常和@Configuration注解搭配使⽤。
使用逻辑
- 如果想将第三⽅的类变成组件,你⼜没有没有源代码,也就没办法使⽤@Component进⾏⾃动配置,这种时候使⽤@Bean就⽐较合适了。
- 不过同样的也可以通过xml⽅式来定义。
- 另外@Bean注解的⽅法返回值是对象,可以在⽅法中为对象设置属性。
@Configuration
- @Configuration 标注的类, @Bean 标注的⽅法。
- @Configuration 标注的类等同于⼀个xml⽂件, @Bean 标注的⽅法等同于xml⽂件⾥的⼀ 个标签
Full模式和Lite模式
- Full模式和Lite模式均是针对于Spring配置类⽽⾔的,和xml配置⽂件⽆关。
- 值得注意的是:判断是Full模式 or Lite模式的前提是,⾸先你得是个容器组件。
- 如果是在公司的业务功能/服务上做开发,使⽤Full模式
- 如果你是个容器开发者,或者你在开发中间件、通⽤组件等,那么使⽤Lite模式是⼀种更被推荐的⽅式,它对 Cloud Native更为友好
Lite模式
官方定义为:在没有标注@Configuration的类里面有@Bean方法就称为Lite模式的配置。
透过源码再看这个定义是不完全正确的,而应该是有如下case均认为是Lite模式的配置类:
- 类上标注有@Component注解
- 类上标注有@ComponentScan注解
- 类上标注有@Import注解
- 类上标注有@ImportResource注解
- 若类上没有任何注解,但类内存在@Bean方法
- 以上case的前提均是类上没有被标注@Configuration
- 在Spring 5.2之后新增了一种case也算作Lite模式:
- 标注有@Configuration(proxyBeanMethods = false),注意:此值默认是true哦,需要显示改为false才算是Lite模式
细心的你会发现,自Spring5.2(对应Spring Boot 2.2.0)开始,内置的几乎所有的@Configuration配置类都被修改为了
@Configuration(proxyBeanMethods = false)
,目的何为?答:以此来降低启动时间,为Cloud Native继续做准备。Lite模式优缺点
优点:
- 运⾏时不再需要给对应类⽣成CGLIB⼦类,提⾼了运⾏性能,降低了启动时间,
- 该配置类可以当作⼀个普通类使⽤:也就是说@Bean⽅法 可以是private、可以是final
缺点:
- 不能声明@Bean之间的依赖,也就是说不能通过⽅法调⽤来依赖其它Bean
- 其实这个缺点还好,很容易⽤其它⽅式“弥补”,⽐如:把依赖Bean放进⽅法⼊参⾥即可
总结:
- Lite模式下,配置类本⾝不会被CGLIB增强,放进IoC容器内的就是本尊
- 该模式下,对于内部类是没有限制的:可以是Full模式或者Lite模式
- 该模式下,配置类内部不能通过⽅法调⽤来处理依赖,否则每次⽣成的都是⼀个新实例⽽并⾮IoC容器内的单例
- 该模式下,配置类就是⼀普通类嘛,所以@Bean⽅法可以使⽤private/final等进⾏修饰(static⾃然也是阔仪 的)
Full模式
在常⻅的场景中, @Bean ⽅法都会在标注有 @Configuration 的类中声明,以确保总是使⽤“Full模式”,这么⼀来,交叉⽅法引⽤会被重定向到容器的⽣命周期管理,所以就可以更⽅便的管理Bean依赖。
何时为Full模式
- 标注有@Configuration注解的类被称为full模式的配置类。
- ⾃Spring5.2后这句话改为下⾯这样我觉得更为精确些:
- 标注有
@Configuration
或者@Configuration(proxyBeanMethods = true)
的类被称为Full模式的配置类 - 当然喽,proxyBeanMethods属性的默认值是true,所以⼀般需要Full模式我们只需要标
@Configuration
注解即可
- 标注有
Full模式优缺点
- 优点:
- 可以⽀持通过常规Java调⽤相同类的@Bean⽅法⽽保证是容器内的Bean,这有效规避了在“Lite模式”下操作时难以跟踪的细微错误。特别对于萌新程序员,这个特点很有意义
- 缺点:
- 运⾏时会给该类⽣成⼀个CGLIB⼦类放进容器,有⼀定的性能、时间开销(这个开销在Spring Boot这种拥有⼤量配置类的情况下是不容忽视的,这也是为何Spring 5.2新增了proxyBeanMethods属性的最直接原因)
- 正因为被代理了,所以@Bean⽅法 不可以是private、不可以是final
- 优点:
SpringBoot
@ConfigurationProperties
@ConfigurationProperties
是springboot提供读取配置⽂件的⼀个注解。其对应的bean的后置处理器为
ConfigurationPropertiesBindingPostProcessor
1
2public class ConfigurationPropertiesBindingPostProcessor
implements BeanPostProcessor, PriorityOrdered, ApplicationContextAware, InitializingBean {}它是实现了BeanPostProcessor接⼝,在bean被实例化后,会调⽤后置处理,递归的查找属性,通过反射注⼊值
对⼤多数属性⽽⾔强制需提供其setter和getter⽅法。 但是属性名称不要求⼀定相同,只需保证配置⽂件的属性和setter⽅法名相同即可。
不过@ConfigurationProperties注解, 只可以把应⽤主配置⽂件的内容读取进来, 要想给Bean赋值, 只能读取主配置⽂件,就是application.properties或者application.yml⽂件
若我们想⾃⼰写⼀个配置⽂件来给bean赋值,我们就可以使⽤该注解
@PropertyResource
我们在resource⾥边新建⼀个student.properties⽂件,并把之前主配置⽂件⾥的内容剪贴进来,并在bean上边加 上注解
1
2
3
4
5
6
7
// value可以添加多个配置⽂件,classpath指的是类路径,表⽰类路径下的student.properties⽂件
public class Student {
//......
}
注⼊bean的三种⽅式
@ConfigurationProperties
读取配置⽂件, 注⼊bean的⽅式配合@Component注解直接进⾏注⼊(主要)
1
2
3
4
5
public class Student {
//......
}使⽤
@EnableConfigurationProperties
,通常配置在标有@Configuration的类上,当然其他@Component注 解的派⽣类也可以,不过不推荐.@EnableConfigurationProperties
的作⽤: 使@ConfigurationProperties
注解的类⽣效,并将标注@ConfigurationProperties
的类注册到spring容器中@EnableConfigurationProperties({DocumentServerProperties.class})
只是让DocumentServerProperties类生效,将其注入到spring容器中
1
2
3
4
5
6
7
8
9
10
public class DocumentServerProperties {
//代码...
}
public class SomeConfiguration {
}使⽤
@Bean
⽅式在标有@Configuration
的类进⾏注⼊,这种⽅式通常可以⽤在对第三⽅类进⾏配置属性注册1
2
3
4
5
6
7
8
9
10
11
12public class ThirdComponent {
...
}
public class SomeConfiguration {
public ThirdComponent thirdComponent(){
return new ThirdComponent();
}
}
@ImportResource
- 导⼊Spring的配置⽂件,让配置⽂件⾥边的内容⽣效.
- 我们在使⽤spring的时候,通常会⽤xml去配置bean然后注⼊数据. 这对 Spring Boot 兼容⽼项⽬⾮常有⽤,因为有些配置⽆法通过 Java Config 的形式来配置就只能⽤这个注解来导⼊。