This blog is mainly for the spring-ioc core springbean assembly error correction of the spring column
https://blog.csdn.net/qq_38108719/article/details/99674379
Corrected as follows
@Autowired and @Resource do not belong to any of the automatic assembly models. This blog will be covered, and there will be source code verification later
Friends who are interested can take a look at Spring's built-in processors. Two of them are dedicated to analyzing the two annotations @Autowired and @Resource.
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
First of all, according to the injection method of inversion of control in the spring framework mentioned on the spring official website, there are only setter methods and construction methods.
Look at the injection model mentioned (4 types)
So how do we use these four? The xml form configuration provided by spring 1.0 version is as follows for all the beans in the file
Or for a single bean as follows
Then we can know that only the xml configuration method can use the automatic assembly model
So why are @Autowired and @Resource not.
When we look for the difference between @Autowired and @Resource on the Internet, we will mention that @Autowired is first bytype and then byname (set method name)
And @Resource is byname first and then bytype, and an error will be reported if not found.
So we will now see below whether it is based on the byname and bytype of the assembly model, or is it based on a technology to search by name and type.
First of all, we know that these annotations provided by the spring framework are updated after spring 2.5
And the spring official website does not mention that these two annotations use any point in the automatic assembly model, as shown in the figure, we can go in and see
The problem we now use code to explain is that the two annotations @Autowired and @Resource do not use any of the automatic injection models.
The environment is a spring traditional xml form to test a bytype in the automatic injection model
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
" default-autowire="byType">
<context:component-scan base-package="org.springframework.work2"></context:component-scan>
<bean id="uService" class="org.springframework.work2.service.UService" >
</bean>
<bean id="tService" class="org.springframework.work2.service.TService">
</bean>
</beans>
public class TService{
UService uService;
public UService getUService() {
return this.uService;
}
public void setUService(UService uService) {
this.uService = uService;
}
}
public class UService {
}
public class Main {
public static void main(String[] args) {
//AnnotationConfigApplicationContext cxc = new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathXmlApplicationContext cxc = new ClassPathXmlApplicationContext("classpath:spring2.xml");
TService tService = (TService) cxc.getBean("tService");
System.out.println(tService.getUService());
}
}
What we need is not the printed result, it is undoubtedly able to be injected normally. We click into the source code to see, the call chain is
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.AbstractBeanFactory#createBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
Let's set the breakpoint first and then re-break the point to come in
Let's take a look at the injection model of this bean through the post processor
And we happen to configure the automatic assembly model in xml is bytype.
Let's now look at the second environment test annotation @Autowired and @Resource
Environment 2 uses the form of annotations
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="org.springframework.work2"></context:component-scan>
<bean id="uService" class="org.springframework.work2.service.UService" >
</bean>
<bean id="tService" class="org.springframework.work2.service.TService">
</bean>
</beans>
package org.springframework.work2.service;
import org.springframework.stereotype.Component;
public class UService {
}
package org.springframework.work2.service;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
public class TService{
@Autowired
UService uService;
public UService getUService() {
return this.uService;
}
public void setUService(UService uService) {
this.uService = uService;
}
}
package org.springframework.work2;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.work2.app.AppConfig;
import org.springframework.work2.service.TService;
import org.springframework.work2.service.UService;
public class Main {
public static void main(String[] args) {
//AnnotationConfigApplicationContext cxc = new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathXmlApplicationContext cxc = new ClassPathXmlApplicationContext("classpath:spring2.xml");
TService tService = (TService) cxc.getBean("tService");
System.out.println(tService.getUService());
}
}
The same breakpoint and the same call chain, we only look at the last call method of these two annotations
Let's print and see the assembly model of this bean
Of course, we can also manually set this assembly model to bytype or byname in this post processor.
beanDefinition.setAutowireMode(0); 0-1-2-3-4...
The two processors here are the processors that parse the two annotations @Autowired and @Resource mentioned above.
Obviously there is no bytype or byname method. The following blog will also prove that the injection technology used by the two annotations @Autowired and @Resource is that type and name have nothing to do with the automatic injection model.