当前位置:网站首页>@Principle of Autowired annotation
@Principle of Autowired annotation
2022-07-25 08:20:00 【Hypnos924】
@Autowired The principle of annotation
Go straight to the topic , First, let's explain @Autowired The use of annotations , That is, automatically meet bean Dependency injection between
@Autowired Use of annotations
meaning : Inject into attributes javaBean, Pass by type set Method for automatic assembly
Replace :
Location : Modifier member variable
Be careful :
[email protected] By default, assemble by type
2. If spring There is no matching class in the container , Then an exception will be reported
NoSuchBeanDefinitionException
3. If spring There are multiple types in the container that can match ,@Autowire The annotation will automatically switch to assemble by name , Such as If not, you will report an error
NoUniqueBeanDefinitionException
@Autowired Annotation principle
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
} else {
List<InjectedElement> elements = new ArrayList();
// Target class to be processed
Class targetClass = clazz;
do {
List<InjectedElement> currElements = new ArrayList();
// Get all the fields of this class through reflection , And traverse each field , And by means of findAutowiredAnnotation The annotation used to traverse each field , And if you use autowired Modify the , Then return to auotowired Related properties
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
MergedAnnotation<?> ann = this.findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = this.determineRequiredStatus(ann);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
MergedAnnotation<?> ann = this.findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0 && this.logger.isInfoEnabled()) {
this.logger.info("Autowired annotation should only be used on methods with parameters: " + method);
}
boolean required = this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
}
}
});
// There are many. @Autowired Embellished notes , All added currElements In this container , Deal with it together
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while(targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
}
Return contains all with autowire An annotation decorated InjectionMetadata aggregate
public InjectionMetadata(Class<?> targetClass, Collection<InjectionMetadata.InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
Get the target class , You can implement dependency injection
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
if (!this.validatedBeanNames.contains(beanName)) {
if (!this.shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList();
PropertyDescriptor[] var6 = pds;
int var7 = pds.length;
for(int var8 = 0; var8 < var7; ++var8) {
PropertyDescriptor pd = var6[var8];
if (this.isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(this.buildExceptionMessage(invalidProperties, beanName));
}
}
this.validatedBeanNames.add(beanName);
}
return pvs;
}
call InjectionMetadata Medium inject Method
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
if (!((Collection)elementsToIterate).isEmpty()) {
Iterator var6 = ((Collection)elementsToIterate).iterator();
while(var6.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
element.inject(target, beanName, pvs);
}
}
}
Call after traversal inject Method
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable {
if (this.isField) {
Field field = (Field)this.member;
// Instantiate and assign values to objects through reflection
ReflectionUtils.makeAccessible(field);
field.set(target, this.getResourceToInject(target, requestingBeanName));
} else {
if (this.checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method)this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, this.getResourceToInject(target, requestingBeanName));
} catch (InvocationTargetException var5) {
throw var5.getTargetException();
}
}
}
In general, its core is reflection , Get all of the target class through reflection Field and Method Information , Then decide whether to be @Autowired annotation , If there is one, it will be assembled automatically , And will need to automatically assemble the elements , Encapsulated into AutowiredFieldElement( For fields ) or AutowiredMethodElement( For methods ) object ;
call AutowiredFieldElement or AutowiredMethodElement Of inject Method , By reflection , Calling the container's getBean() Method to find what needs to be injected Bean object , Then inject into the target Bean in ;
边栏推荐
- Machine learning theory and case analysis (Part1) -- Fundamentals of machine learning
- MVC mode three-tier architecture
- Sqlserver has opened the CDC table. Why can we only pull the full amount of data and can't recognize the incremental data
- DIY can decorate the mall system, you can also have!
- Svg creative underline style JS special effect
- 刷题《剑指Offer》day02
- C 43. Get UDP available ports
- Niuke dynamic planning training
- Redis fragment cluster
- Vscode remote connection server, switch to go version
猜你喜欢

A simple SQL injection shooting range exercise

Advanced C language (11) - user defined data types

Introduction to machine learning (I): understanding maximum likelihood estimation in supervised learning

Blue and white porcelain used by Charles

How to set up a personal website for free

RK3399开发板I2C4挂载EEPROM实例

ArcGIS Pro脚本工具(10)——从图层生成.stylx样式符号

R language error

Hotel room management system based on jsp+servlet+mysql

滴滴 - eta(Estimate the Travel Time)
随机推荐
Raspberry pie 4B parsing PWM
CAS操作
In depth analysis of yolov7 network architecture
Redis learning
Vscode remote connection server, switch to go version
[dark horse programmer] redis learning notes 001: introduction to redis + five basic data types
【5G NR】3GPP常用协议整理
If there is complex select nesting in the SQL of the flick CDC, when it encounters the binlog of delete, it will
TCGA simple download tool V16 installation error
阿里云服务的网络解决方案
【黑马程序员】Redis学习笔记003:Redis事务
Learn when playing No 2 | learning is too boring? Learning maps lets you learn and play
Dijkstra序列(暑假每日一题 5)
nuscenes数据集3D MOT demo,端到端的目标检测和跟踪,检测跟踪联合框架
机器学习理论及案例分析(part2)--回归
[dark horse programmer] redis learning notes 002: persistence: RDB and AOF
Raspberrypico serial communication
Didi eta (estimate the travel time)
Problems easily ignored by POM
Ensembles in RNA counts data in TCGA_ ID to gene_ Method of ID