Spring核心技术总结
2023-03-24 17:11:51 19 举报
AI智能生成
Spring学习时主要关注点
作者其他创作
大纲/内容
常用注解
@Value
普通字符串
@Value("张三")
直接把字符串赋值给当前字段
占位符
@Value("${userName}")
先进行占位符的替换,然后将替换后的字符串赋值给当前字段
根据操作系统环境变量、JVM环境变量、properties文件作为替换的数据来源
SpringEL
@Value("#user.userName")
先解析Spring表达式,将结果赋值给当前字段
注意:解析Spring表达式的结果可能是字符串,也可能是一个Bean对象
基于@Value做扩展
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Value("${local.server.port}")
public @interface LocalServerPort{
}
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Value("${local.server.port}")
public @interface LocalServerPort{
}
@Bean
autowire
NO
不会自动注入
BY_NAME
根据set方法所对应的属性名查找Bean对象进行注入
BY_TYPE
根据set方法所对应的属性类型查找Bean对象进行注入
注意:跟@AutoWired注解提供的依赖注入功能是完全对立的
autowireCandidate
默认为true,表示可以用来作为依赖注入的候选者;改为false之后,表示不能被用来做依赖注入的候选者
@Bean不仅仅只能写在@Configuration中,还可以写在@Component中
@Bean除了可以写在方法上,也能写在某个注解上,使得可以自定义注解来模拟@Bean的功能
比如我们可以实现一个@PrototypeBean
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Bean
@Scope("prototype")
public @interface PrototypeBean{
}
@Retention(RetentionPolicy.RUNTIME)
@Bean
@Scope("prototype")
public @interface PrototypeBean{
}
@ComponentScan
顾名思义,@ComponentScan就是用来扫描@Component注解的,默认情况下Spring会把扫描路径下所有@Componet注解的类扫描出来,并生产对应的Bean对象
includeFilters
可以自定义过滤条件,符合条件的才是Bean
ANNOTATION
可以制定某个注解,表示类上有这个注解的才是Bean
ASSIGNABLE_TYPE
可以制定某个类,表示只有这个类才是Bean
ASPECTJ
可以制定一个AspectJ的表达式,表示符合这个表达式的才是Bean
REGEX
可以制定一个正则表达式,表示符合这个表达式的才是Bean
CUSTOM
可以制定一个TypeFilter实现类,自定义匹配逻辑
excludeFilters
可以自定义过滤条件,符合条件的不是Bean
类型同上,只不过符合条件的就排除
扫描索引
跟@ComponentScan注解没有关系,跟扫描有关
默认情况下,Spring扫描时有可能需要扫描很多很多的类,具体看制定的路径下类的数量,那么这个过程就比较浪费时间
在Spring中提供了一种加快扫描的方式,也就是扫描索引,不过这个索引得程序员自己去创建一个META-INFO/spring。components文件,并在这个文件中制定哪些类是Bean,对与Spring而言,它就会去读取这个文件中的内容,并把文件中制定的类当作Bean,而不用去扫描了,这样提高了扫描速度
@Conditional
条件注解
TYPE上使用时
Spring在扫描时,如果发现一个类上存在@Conditional注解,那么就会获取该注解中所配置的Condition接口实现类,并调用其matches方法,判断是否匹配,匹配则把该类作为Bean
METHOD上使用时
当把@Conditional注解加载一个@Bean注解的方法上时,Spring在解析该@Bean方法时,会发现存在一个@Conditional注解,从而去判断是否符合当前条件,符合才会生成对应的Bean
Condition接口
ConditionContext
可以拿到一些Spring容器相关的东西
BeanFactory
比如可以用来判断当前BeanFactory中是否存在某个Bean
Environment
比如可以用来判断当前环境变量中是否存在某个key
ClassLoader
比如可以用来判断当前是否存在某个类
AnnotatedTypeMetadata
@Conditional注解所在的类上的元数据信息
比如可以用来判断当前类上是否存在某个注解
@Autowried
FIELD
表示字段注入
METHOD
表示Set方法注入
CONSTRUCTOR
表示构造方法注入
ANNOTATION_TYPE
表示可以写在其他注解上,使得该注解拥有@Autowired注解相关功能
PARAMETER
尽管@Autowired注解可以加在普通方法或构造方法的参数前,但是Spring框架中大部分地方都忽略了这种情况下的@Autowired注解,仅仅在spring-test模块中对于JUnit Jupiter的支持中,支持了参数前的@Autowired注解
required属性
默认为true,表示一定要给某个属性找到Bean对象并赋值,如果找不到Bean对象则会报错
构造方法上required属性会失效,相当于一直为true
static
static字段或方法上不会进行依赖注入的
@Lazy
TYPE
当把@Lazy注解写在某个类上(该类上有@Component注解)时,表示该Bean是一个懒加载的Bean,表示该Bean是在用到时才去创建,而不是Spring启动时创建
当把@Lazy注解写在一个@Configuration注解所在类上时,表示该类内部所有@Bean所定义的Bean都是懒加载的Bean
FIELD
当把@Lazy注解加在一个字段上时,Spring会给该属性赋值一个CGLIB所生成的代理对象,当该代理对象执行某个方法时,才会真正的根据字段的类型和名字从Spring容器中找到某个Bean对象,并执行该Bean对象所对应的方法
METHOD
当把@Lazy注解写在一个@Autowired注解所在方法上时,那么Spring会给该方法的所有入参赋值一个代理对象
PARAMETER
当把@Lazy注解写在一个@Autowired注解所在方法的某个参数前时,那么Spring会给该入参赋值一个代理对象
CONSTRUCTOR
当把@Lazy注解写在一个@Autowired注解所在构造方法上时,那么Spring会给该方法的所有入参赋值一个代理对象
注意:可以解决循环依赖
@Resource
没有制定name
先判断字段名字所对应的Bean是否存在,如果存在则把这个Bean赋值给属性,如果不存在则根据字段类型找Bean
制定了name
制定了名字,就只根据名字去找,找到了就用,找不到就报错
注意:@Resource注解是JDK层面定义的,Spring负责实现,负责提供对这个注解的支持
@Configuration
被@Configuration注解修饰的类,首先是一个Bean,并且是一个配置Bean
什么是配置Bean?
有@Configuration注解
proxyBeanMethods默认t为rue,表示是Full配置Bean
proxyBeanMethods为false,表示是Lite配置Bean
无@Configuration注解
存在@Component注解就是Lite配置Bean
存在@ComponentScan注解就是Lite配置Bean
存在@Import注解就是Lite配置Bean
存在@ImportResource注解就是Lite配置Bean
存在@Bean注解的方法就是Lite配置Bean
配置Bean有什么用?
对于配置Bean,不仅仅只是存放到Spring容器中,Spring还会去解析配置Bean
不如处理@ComponentScan就会去扫描
比如处理@Improt注解就会将某个类导入成为Bean
比如处理@Bean就会解析对应方法生成Bean
proxyBeanMethods
true
配置Bean对应的是配置类的代理对象
false
配置Bean对应的是配置类的普通对象
@Import
普通类型
直接将该类当作Bean
ImportSelector类型
将SelectImport()方法返回的类当作Bean
DeferredImportSelector类型
将selectImport()方法返回的类当作Bean
与ImportSelector类型的区别在于selectImport()方法执行时机不同
ImportBeanDefinitionRegistrar类型
在registerBeanDefinitions()方法中注册BeanDefinition
@Lookup
@Lookup注解的作用在官网上叫做方法注入
@Autowired、@Resource、@Value是属性注入,是给某个属性赋值
@Lookup注解的作用是给某个方法赋值一个Bean,所以叫方法注入(和Set方法、构造方法注入做区分),在调用这个方法时会返回所制定的Bean对象
正常情况下抽象类是不能成为Bean对象的,但是如果抽象类中的抽象方法上用了@Lookup注解,那么最终也能产生一个Bean对象,并且该Bean对象可以调用该抽象方法,并返回制定的Bean对象
MethodReplacer
方法替换器
@Primary
在Spring容器中可能存在一个类型的多个Bean对象,这是可以通过在某个Bean对象上使用@Primary注解标识该Bean作为这个类型下的主Bean,在依赖注入时会优先使用
Bean相关
注册一个Bean有哪些方式
@Component
@Configuration
@Service
@Controller
@Repository
@Bean
通过解析某个方法作为Bean
@Import
导入类或BeanDefinition作为Bean
@ImportResource
导入一个spring.xml文件,通过解析该文件注册Bean
BeanDefinitionRegistryPostProcessor
通过注册BeanDefinition来注册Bean
FactoryBean
SmartFactoryBean
将自己new的一个对象注册为Bean
applicationContext.registerBean()
通过Supplier接口来提供一个对象作为Bean
applicationContext.register()
直接将某个类注册为Bean
applicationContext.registerBeanDefinition()
注册一个BeanDefinition,就相对于注册了一个Bean
Bean的作用域
单例
单例池
通过一个Map来实现
多例
无需额外支持,每次创建一个Bean直接返回
Request
request.getAttribute()
request.setAttribute()
Session
session.getAttribute()
session.setAttribute()
application
servletContext.getAttribute()
servletContext.setAttribute()
Bean创建的生命周期
BeanDefinition合并
一个Bean可以有自己的父Bean,那么子Bean就会继承父Bean中所定义的各种属性,比如scope
类加载
在创建一个对象前,得确保对应的类已经加载了
注意:在扫描时,是利用的ASM继续去解析的类,并没有加载类
实例化前
提供了一个扩展点,可以让程序员在这个位置控制某个Bean对象的创建
实例化
Supplier创建对象
工程方法创建对象
推断构造方法
BeanDefinition后置处理
提供了一个扩展点,可以让程序员在这个位置来修改BeanDefinition,比如制定初始化方法
实例化后
提供了一个扩展点,可以让程序员在这个位置针对Bean对象做一些处理,比如执行方法、给某个属性赋值等
属性填充
给某个属性赋值
处理@Autowired注解
处理@Resource注解
处理@Value主键
等等...
Aware回调
BeanNameAware
回传beanName给bean对象
BeanClassLoaderAware
回传classLoader给bean对象
BeanFactoryAware
回传beanFactory给bean对象
初始化前
处理@PostConstruct注解
执行对应的方法
EnvironmentAware
回传环境变量给bean对象
EmbeddedValueResolverAware
回传占位符解析器给bean对象
ResourceLoaderAware
回传资源加载器给bean对象
ApplicationEventPublisherAware
回传事件发布器给bean对象
MessageSourceAware
回传国际化资源给bean对象
ApplicationContextAware
回传Spring容器ApplicationContext给bean对象
初始化
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调佣其afterPropertiesSet()方法
执行BeanDefinition中制定的初始化方法
初始化后
判断当前Bean是否进行AOP,如果需要则进行AOP
SmartInitializingSigleton
当所有的非懒加载单例Bean都创建好之后,会判断是否存在某个单例Bean实现了SmartInitializingSingleton接口,如果实现了就执行afterSingletonsIistantiated()方法
实用工具
国际化
MessageSource
更方便进行国际化操作
资源加载
context.getResource()
更方便读取某个资源
文件资源
网络资源
获取运行时环境
context.getEnvironment()
更方便获取环境变量
操作系统环境变量
JVM环境变量 -D
properties文件
事件发布
ApplicationListener
某个类作为事件监听器
@EventListener
某个方法作为事件监听器
Order比较器
OrderComparator
利用Ordered接口来制定顺序
AnnottionAwareOrderComparator
利用@Order注解来制定顺序
类的元数据读取器
SimpleMetadataReaderFactory
读取类上各种信息
类名
类上的注解
类中的方法
等等...
其他
依赖注入有哪些方式?
autowire mode
可以理解为Spring自带的自动注入功能,和@Autowired注解没有关系
主要利用的是类中的Set方法
by type
by name
@Autowired
用@Autowired注解来标识要给哪个属性进行自动注入
属性注入
先by type,再by name
setter方法注入
待注入参数为private且不能用final修饰,存在安全问题对象可能被修改
构造方法注入(官方推荐)
用于类的构造方法上,对参数注入(一个构造方法的时候,可以不加@Autowired注解)
@Resource
用@Resource注解来标识要给哪个属性进行自动注入
可以加在字段上
先by type,再by name
可以加在方法上
先by type,再by name
@Value
用@Value注解来给属性赋值
可以加在字段上
可以加在方法上
自定义BeanPostProcessor
处理自定义注解
Spring AOP有哪些使用方式?
ProxyFactory
代理对象工程,封装了JDK动态代理和CGLIB
ProxyFactoryBean
利用FactoryBean机制将代理对象作为一个Bean
BeanNameAtuoProxyCreator
制定某个beanName让Spring对其进行AOP
DefaultAdvisorAutoProxyCreator
制定某个Advisor,让Spring对其匹配的Bean对象进行AOP
@EnableAspectAutoProxy
开启支持AspectJ
获取ApplicaitonContext有哪些方式?
ApplicationContextAware
通过ApplicationContextAware回调,Spring会把ApplicationContext传入setApplicationContext方法
@Autowired
因为Spring在进行依赖注入时做了特殊处理,也支持将ApplicationContext对象注入给某个字段
Spring类型转化有哪些方式?
PorperEditor
利用JDK中自带的
ConversionService
Spring中实现的
TypeConverter
合二为一
Spring中有哪些父子?
父子类
父子BeanDefinition
父子BeanFactory
父子ApplicationContext
收藏
0 条评论
下一页