研究spring源码,官网是一定要参考的
自动注入
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire
自动注入模型
自动注入与手动注入
spring工厂在生成对象之后(没有进行属性填充不是bean,bean需要属性填充和经历完整生命周期),需要进行属性填充通过spring后置处理器的postProcessPropertyValues()方法
首先搞明白什么是自动注入,自动注入也可以叫做自动装配(springboot也有一个自动装配,springboot的应该叫做自动配置和这里说的自动注入是两回事,笔者不是什么大牛或者权威;所以读者如果你坚持认为springboot也叫自动装配那也无可厚非,只是在这篇文章里面所谓的自动注入就是自动装配,关于springboot的自动配置我以后再说),自动注入需要相对于手动装配来说。
DI(依赖注入)一共有两种主要的变体,分别是基于构造方法的依赖注入和基于setter(setXxxx(…))的依赖注入,不管是手动装配还是自动装配都是基于这两种方式或者变体方式来的;但是这里一定要回答到主要和变体两个名词,因为有的注入方式就不是这两种,而是这两种其中一种的变体方式;比如在一个类的属性上面加@Autowired,这种方式注入属性的方式就是利用了java的反射知识,field.set(value,targetObject);所以@Autowired这种注入的方式是setter注入方式的一种变体
xml或注解实现自动注入
首先根据四种自动注入模型进行理解,默认情况是no,BeanDefinition的属性autowireMode是AUTOWIRE_NO(0)。不自动进行注入。如果通过xml或修改BeanDefinition属性值为AUTOWIRE_BY_NAME(1),AUTOWIRE_BY_TYPE(2)可以
通过实现BeanFactoryPostProcessor可以修改beanDefinition 的AutowireMode
xml配置实现自动装配
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byType">
<!--自动装配-->
<bean id="userService" class="com.service.Uservice">
</bean>
<bean id="indexService" class="com.service.IndexService">
</bean>
</beans>
package com.service;
public class IndexService {
}
package com.service;
public class UserService {
IndexService indexService;
//如果是自动装配需要提供setter方法或提供构造方法
//构造方法
public UserService(IndexService indexService){
this.indexService=indexService;
}
//set方法
public void setIndexService(IndexService indexService) {
this.indexService = indexService;
}
public void xx(){
System.out.println(indexService);
}
}
@ImportResource("classpath:spring.xml")
public class AppConfig {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext( AppConfig.class );
UserService userService = (UserService) ac.getBean("userService" );
userService.xx( );
}
}
注解实现自动装配
package com.service;
import org.springframework.stereotype.Component;
@Component
public class IndexService {
}
package com.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class UserService {
IndexService indexService;
//如果是自动装配需要提供setter方法或提供构造方法
//构造方法
public UserService(IndexService indexService){
this.indexService=indexService;
}
//set
public void setIndexService(IndexService indexService) {
this.indexService = indexService;
}
public void xx(){
System.out.println(indexService);
}
}
package com.service;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition beanDefinition = (GenericBeanDefinition)beanFactory.getBeanDefinition( "userService");
beanDefinition.setAutowireMode( 1 );
//beanDefinition.setAutowireMode( 2 );
System.out.println(beanDefinition.getAutowireMode());
}
}
package com;
@Configuration
@ComponentScan("com.service")
public class AppConfig {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext( AppConfig.class );
UserService userService = (UserService) ac.getBean("userService" );
userService.xx( );
}
}
通过源码测试
populateBean.pngautowireByName.png
反射调用set方法.png
最后调用到程序得setIndexService()方法
所以可以这样理解:
自动注入模型有四种:no byname bytype constructor
自动注入方法有set和构造器方式
官网https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-constructor-injection
使用@Autowired或@Resource注入
是一种手动注入
autowire.png inject.png
fieldset.png
@autowire属性注入调用链
AbstractAutowireCapableBeanFactory#populateBean
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
InjectionMetadata#inject
AutowiredFieldElement#inject
field.set(bean, value)
@autowire注入的实现类有多个
package com.service;
public interface C {
}
package com.service;
@Component
public class IndexService implements C {
}
package com.service;
@Component
public class IndexService1 implements C {
}
package com.service;
@Component
public class UserService {
@Autowired
C indexService1;
public void xx(){
System.out.println(indexService1);
}
}
basedtype.png
basedname.png
先通过类型type查找有两个,再通过name进行查找
所以,@autowire先通过type查找,如果查找到多个则再通过name查找,如果没有匹配的name则报错
@Resource
先通过name再通过bype进行查找
调用链
CommonAnnotationBeanPostProcessor#postProcessPropertyValues
InjectionMetadata#inject
InjectedElement#inject
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
field.set(target, getResourceToInject(target, requestingBeanName));
resource.png
可以证明先name,再从type查找
通过name没查找到则调用链如下
DefaultListableBeanFactory#resolveDependency
DefaultListableBeanFactory#doResolveDependency
DefaultListableBeanFactory#findAutowireCandidates
如果根据name查找到而类型不匹配则报错
populateBean方法
AbstractAutowireCapableBeanFactory#populateBean方法是实现注入的地方
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//自动注入赋值
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
//手动注入 注解@Autowired 与@Resource
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);//自动注入实现
}
}
autowireByName()和autowireByType()查找
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
网友评论