spring-ioc-automatic assembly

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

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-autowired-annotation

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.

 

 

 

Guess you like

Origin blog.csdn.net/qq_38108719/article/details/103061155