当前位置:网站首页>Annotation @autowired how to assemble automatically
Annotation @autowired how to assemble automatically
2022-07-26 05:01:00 【l1050188952】
One 、 Concept :@Autowired yes spring frame 2.5 After that , Used to simplify bean It needs to define attributes to realize the annotation of automatic assembly , One of the most common annotations of night markets .
Two 、 Role position : Can be modified in the method , Parameters, annotations and other attributes ( Here is the source code )
// The positions that can be decorated include , Construction method , Common method , Parameters ,
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
/* Field ,*/ /* annotation */
ElementType.FIELD, ElementType.ANNOTATION_TYPE})
// The retention policy is at run time
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
// Declared dependent properties The default is true
boolean required() default true;
}From what we see Autowired There is no code about automatic assembly in the source code , The code to complete the automatic assembly is in AutowiredAnnotationBeanPostProcessor Class .

< One > Find the element to be assembled and save ( analysis Autowired)
1. You can see ,AutowiredAnnotationBeanPostProcessor Realized
MergedBeanDefinitionPostProcessor Interface , rewrite postProcessMergedBeanDefinition() Method , Pre parsing of the injection type implemented .
// Preloading method in the source code
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
InjectionMetadata metadata
= this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}2. The main logic is in findAutowiringMetadata() Method . This method is mainly to find the elements that need to be automatically assembled , This method calls buildAutowiringMetadata() Method to build metadata information .
// findAutowiringMetadata Source code
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// cache Bean The name of
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
// Determine whether the cache exists
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// The goal is Bean Metadata information
metadata = this.buildAutowiringMetadata(clazz);
// Deposited in the cache
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}3. The core logic is buildAutowiringMetadata() In the method
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
LinkedList<InjectedElement> elements = new LinkedList();
Class targetClass = clazz;
do {
LinkedList<InjectedElement> currElements = new LinkedList();
// Get all the fields in the target class through reflection , And traverse each field , And then through findAutowiredAnnotation() Method to determine whether the field uses @Autowired and @Value modification ,
// If the field is @Autowired and @Value modification , Then the relevant attribute information of the annotation is returned
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
AnnotationAttributes ann = this.findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// Get @Autowired Annotated required() Value
boolean required = this.determineRequiredStatus(ann);
// Seal the field as AutowiredFieldElement object
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
}
});
// Reflection gets the target Bean All the ways
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
AnnotationAttributes ann = this.findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0 && this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation should only be used on methods with parameters: " + method);
}
boolean required = this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// Seal the field as AutowiredMethodElement object
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
// Loop through the elements of the parent class that need to be automatically assembled
while(targetClass != null && targetClass != Object.class);
// Encapsulate all the meta information related to automatic injection corresponding to the target class into InjectionMetadata, Then merge into Bean In the definition
return new InjectionMetadata(clazz, elements);
}buildAutowiringMetadata() Method steps :
1》 Get all the fields in the target class through reflection and traverse , And then through findAutowiredAnnotation() Method to determine whether the field uses @Autowired and @Value modification , If the field is @Autowired and @Value modification , Then all attribute information of the annotation is returned .
2》 Get all the methods in the target class through reflection ;
3》 Meta information parsed into fields and methods is saved to List<InjectionMetadata.InjectedElement> elements Collection , The field corresponds to AutowiredFieldElement type , Method corresponds to AutowiredMethodElement type .
4》 Encapsulate all the meta information related to automatic injection corresponding to the target class into InjectionMetadata class , return
buildAutowiringMetadata() After method execution , The parsed automatic injection related information will be saved to the cache injectionMetadataCache
4.postProcessMergedBeanDefinition() Method passes the attribute information to be injected through checkConfigMembers()
It's encapsulated in InjectionMetadata Class , It contains all the information of assembly and inner assembly classes .
public class InjectionMetadata {
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
private final Collection<InjectionMetadata.InjectedElement> injectedElements;
@Nullable
private volatile Set<InjectionMetadata.InjectedElement> checkedElements;
public InjectionMetadata(Class<?> targetClass, Collection<InjectionMetadata.InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectionMetadata.InjectedElement> checkedElements = new LinkedHashSet(this.injectedElements.size());
Iterator var3 = this.injectedElements.iterator();
while(var3.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var3.next();
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isDebugEnabled()) {
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}< Two > Auto injection properties
AutowiredAnnotationBeanPostProcessor Indirectly realized InstantiationAwareBeanPostProcessor Interface , So it will be implemented to postProcessProperties() Method to automatically inject attributes .
*postProcessProperties() Method :
1. call findAutowiringMetadata() Method , Try from cache injectionMetadataCache Get the corresponding injection meta information , If the cache does not exist , Will execute buildAutowiringMetadata() obtain ;
2. loop InjectionMetadata Of injectedElements attribute , Call all InjectionMetadata.InjectedElement.inject(bean, beanName, pvs) Method , Set the value of the attribute by reflection ;
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// loop elementsToIterate, call InjectionMetadata.InjectedElement.inject Method , Set the value of the attribute by reflection ;
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
summary : The above is divided into two parts , One is analysis @Autowired Method , Get the properties and methods of the target class from reflection , To deposit injectionMetadataCache in , The key is buildAutowiringMetadata() Method . The second is to automatically inject attributes , Or the way of reflection , take injectionMetadataCache Zhongyuan information ,inject(bean, beanName, pvs) Method is the key
边栏推荐
- [weekly translation go] how to write your first program with go
- Building blocks for domestic databases, stonedb integrated real-time HTAP database is officially open source!
- 汉字风格迁移篇---通过生成对抗网络学习一对多程式化汉字的转换和生成
- 2022 a.static query on tree (tree section)
- 域名解析过程全分析,就着文字理解更佳
- Mysql主从同步及主从同步延迟解决方案
- Briefly describe the application fields of WMS warehouse management system
- 批量将PPM格式图片转化为JPG格式
- 你对“happen-before原则”的理解可能是错的?
- [mathematical modeling] analytic hierarchy process (AHP)
猜你喜欢

Kubernetes 进阶训练营 调度器

Icml2022 | imitation learning by evaluating the professional knowledge of the presenter

Database startup message: ora-29702: error occurred in cluster group service

基于R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习

Calculate the curvature of discrete points (matlab)
![[weekly translation go] how to write your first program with go](/img/77/cf77a46340a39797382fd7b60517d5.png)
[weekly translation go] how to write your first program with go

JVM第二讲:类加载机制

注解@Autowired如何自动装配

JVM第五讲:纵横数据如何应对洪峰推送

数据库启动报:ORA-29702: error occurred in Cluster Group Service
随机推荐
遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等领域中的应用
2022 Henan Mengxin League game (3): Henan University L - synthetic game
JVM第五讲:纵横数据如何应对洪峰推送
The integrated real-time HTAP database stonedb, how to replace MySQL and achieve nearly 100 times the improvement of analysis performance
5个chrome简单实用的日常开发功能详解,赶快解锁让你提升更多效率!
CountLaunch Demo的测试
奥特学园ROS笔记--6
Character function and string function (I)
MySQL八股知识点:从入门到删库
SWAT模型在水文水资源、面源污染模拟中的实践技术
Alibaba three sides: how to solve the problems of MQ message loss, duplication and backlog?
Learn to map with nature medicine -- complex heat map
LeetCode - 单调栈与单调队列
【云原生 | 17】容器的四种网络模式
MODFLOW Flex、GMS、FEFLOW、HYDRUS实践应用
2022 Hangdian multi school DOS card (line segment tree)
创建MySQL数据库的两种方式
vector详解和迭代器失效问题
How many holes have you stepped on in BigDecimal?
【ACWing】2983. 玩具