当前位置:网站首页>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
边栏推荐
- What are the restrictions on opening futures accounts? Where is the safest place to open an account?
- C language lseek() function: move the read and write location of the file
- There was an unexpected error (type=method not allowed, status=405)
- 有ggjj看看这个问题没,是否缓存导致跨域问题?
- Excel VBA:将多个工作表保存为新文件
- 2022 Henan Mengxin League game (3): Henan University a - corn cannon
- minipcie接口CAN卡解决工控机扩展CAN通道的难题 minipcie CAN
- 创建MySQL数据库的两种方式
- Use field parameters for report translation
- [300 + selected interview questions from big companies continued to share] big data operation and maintenance sharp knife interview question column (VIII)
猜你喜欢

What is the real HTAP? (1) Background article

Interprocess communication

奥特学园ROS笔记--6

Redis solves the problem of oversold inventory

The first open source MySQL native HTAP database in China will be released soon! Look at the three highlights first, limited to the surrounding areas, waiting for you~

2022 Henan Mengxin League game (3): Henan University L - synthetic game

vector详解和迭代器失效问题

ES6模块化+CommonJS

Switch and router technology: dynamic routing protocol, rip routing protocol and OSPF routing protocol

SQL加解密注入详解
随机推荐
Recursive implementation of exponential enumeration
minipcie接口CAN卡解决工控机扩展CAN通道的难题 minipcie CAN
Distance between bus stops: simple simulation problem
Whether the SQL that fails to execute MySQL is counted into the slow query?
有ggjj看看这个问题没,是否缓存导致跨域问题?
columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by mysql8.0解决办法
Axi protocol (4): signals on the Axi channel
[mathematical modeling] basic knowledge of MATLAB
软考回顾及计划
迁移服务器,重新配置数据库(数据库无监听,启动监听报TNS-12545、TNS-12560、TNS-00515错误)
Principle of image nonlocal mean filtering
Database startup message: ora-29702: error occurred in cluster group service
A material of machine learning
Building blocks for domestic databases, stonedb integrated real-time HTAP database is officially open source!
Google Emoji guessing game helps parents guide their children to surf the Internet safely
Excel VBA:按日期汇总计算输出结果(sumif)
vector详解和迭代器失效问题
Mysql主从同步及主从同步延迟解决方案
Stm32fsmc extended SRAM
LeetCode - 单调栈与单调队列