首先分两种:
在XML中定义Bean时,就是手动注入,因为是程序员手动给某个属性指定了值。
上面这种底层是通过set方法进行注入。
上面这种底层是通过构造方法进行注入。
所以手动注入的底层也就是分为两种:
自动注入又分为两种:
在XML中,我们可以在定义一个Bean时去指定这个Bean的自动注入模式:
比如:
或者
//@Bean(autowire = Autowire.BY_NAME)
@Bean(autowire = Autowire.BY_TYPE)
public UserServiceImpl userService(){
return new UserServiceImpl();
}
这么写,表示Spring会自动的给userService中所有的属性自动赋值(不需要这个属性上有@Autowired注解,但需要这个属性有对应的set方法)。
我们看一下源码中是如何实现的,org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
方法中的代码:
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
如果我们设置的时byName,执行autowireByName方法:
进来首先执行
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
获取当前Bean中能进行自动注入的属性名
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 什么样的属性能进行自动注入?
// 1.该属性有对应的set方法
// 2.没有在ignoredDependencyTypes中
// 3.如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中
// 4.属性类型不是简单类型,比如int、Integer、int[]
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
注意:会有一个BeanDefinition的后置处理(MergedBeanDefinitionPostProcessor,我们可以在这个时候修改BeanDefinition的PropertyValues,告诉BeanDefinition将某个值赋给属性,但是不是直接赋值,相当于是记录一下赋值关系,所以这里有个判断
当前BeanDefinition的PropertyValues中没有这个字段才会去自动注入,如果有的话就不会处理,意思就是如果我们自己通过BeanDefinition给某个字段赋值,以我们自己设置为准。
Spring会去解析当前类,把当前类的所有方法都解析出来,Spring会去解析每个方法得到对应的PropertyDescriptor对象,PropertyDescriptor(属性描述器)中有几个属性:
get方法的定义是: 方法参数个数为0个,并且 (方法名字以"get"开头 或者 方法名字以"is"开头并且方法的返回类型为boolean)
**set方法的定义是:**方法参数个数为1个,并且 (方法名字以"set"开头并且方法返回类型为void)
执行完unsatisfiedNonSimpleProperties会返回当前Bean中能进行自动注入的属性名(是set方法后得到的名字)
然后遍历每个属性名,并去获取Bean对象,并设置到pvs中
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 记录一下propertyName对应的Bean被beanName给依赖了
registerDependentBean(propertyName, beanName);
所以,Spring在通过byName的自动填充属性时流程是:
如果我们设置的时byName,执行autowireByType方法,和byName类似
Spring在通过byType的自动填充属性时流程是:
注意:autowireByName和autowireByType方法都没有直接将得到bean赋值给属性,而是记录到了BeanDefinition的PropertyValues中
pvs.add(propertyName, bean);
同样在实例化完成之后,执行属性赋值之前,会有一个BeanDefinition的后置处理(MergedBeanDefinitionPostProcessor,我们可以在这个时候修改BeanDefinition的PropertyValues,但是同样没有直接赋值给属性,赋值操作是在执行完InstantiationAwareBeanPostProcessor.postProcessProperties(@AutoWired,@Resource)之后
以上,分析了autowire的byType和byName情况,那么接下来分析constructor,constructor表示通过构造方法注入,其实这种情况就比较简单了,没有byType和byName那么复杂。
如果是constructor,那么就可以不写set方法了,当某个bean是通过构造方法来注入时,spring利用构造方法的参数信息从Spring容器中去找bean,找到bean之后作为参数传给构造方法,从而实例化得到一个bean对象,并完成属性赋值(属性赋值的代码得程序员来写)。
我们这里先不考虑一个类有多个构造方法的情况,后面单独讲推断构造方法。我们这里只考虑只有一个有参构造方法。
其实构造方法注入相当于byType+byName,普通的byType是根据set方法中的参数类型去找bean,找到多个会报错,而constructor就是通过构造方法中的参数类型去找bean,如果找到多个会根据参数名确定。
另外两个:
可以发现XML中的自动注入是挺强大的,那么问题来了,为什么我们平时都是用的@Autowired注解呢?而没有用上文说的这种自动注入方式呢?
@Autowired注解相当于XML中的autowire属性的注解方式的替代。这是在官网上有提到的。
Essentially, the @Autowired annotation provides the same capabilities as described in Autowiring Collaborators but with more fine-grained control and wider applicability
翻译一下: 从本质上讲,@Autowired注解提供了与autowire相同的功能,但是拥有更细粒度的控制和更广泛的适用性。
注意:更细粒度的控制。
XML中的autowire控制的是整个bean的所有属性,而@Autowired注解是直接写在某个属性、某个set方法、某个构造方法上的。
再举个例子,如果一个类有多个构造方法,那么如果用XML的autowire=constructor,你无法控制到底用哪个构造方法,而你可以用@Autowired注解来直接指定你想用哪个构造方法。
同时,用@Autowired注解,还可以控制,哪些属性想被自动注入,哪些属性不想,这也是细粒度的控制。
但是@Autowired无法区分byType和byName,@Autowired是先byType,如果找到多个则byName。
那么XML的自动注入底层其实也就是:
上文说了@Autowired注解,是byType和byName的结合。
@Autowired注解可以写在:
而这种底层到了:
在创建一个Bean的过程中,Spring会利用AutowiredAnnotationBeanPostProcessor的**postProcessMergedBeanDefinition()**找出注入点并缓存,执行的时间是在实例化完成之后,执行属性赋值之前,会执行BeanDefinition的后置处理(MergedBeanDefinitionPostProcessor)
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
findAutowiringMetadata方法中会解析注入点并放入缓存
buildAutowiringMetadata找注入点的流程为:
// 遍历targetClass中的所有Field
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// field上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
// static filed不是注入点,不会进行自动注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 构造注入点
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
遍历当前类的所有的属性字段Field
查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段是一个注入点
如果字段是static的,则不进行注入
获取@Autowired中的required属性的值
将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到currElements集合中。
// 遍历targetClass中的所有Method
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// method上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// static method不是注入点,不会进行自动注入
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// set方法最好有入参
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
遍历当前类的所有方法Method
判断当前Method是否是桥接方法,如果是找到原方法
查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法是一个注入点
如果方法是static的,则不进行注入
获取@Autowired中的required属性的值
将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中。
do{
.....
}
while (targetClass != null && targetClass != Object.class);
遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。
最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合对象,并缓存。
@Component
@Scope("prototype")
public class OrderService {
}
@Component
@Scope("prototype")
public class UserService {
@Autowired
private static OrderService orderService;
public void test() {
System.out.println("test123");
}
}
看上面代码,UserService和OrderService都是原型Bean,假设Spring支持static字段进行自动注入,那么现在调用两次
问此时,userService1的orderService值是什么?还是它自己注入的值吗?
答案是不是,一旦userService2 创建好了之后,static orderService字段的值就发生了修改了,从而出现bug。
public interface UserInterface {
void setOrderService(T t);
}
@Component
public class UserService implements UserInterface {
private OrderService orderService;
@Override
@Autowired
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public void test() {
System.out.println("test123");
}
}
UserService对应的字节码为:
// class version 52.0 (52)
// access flags 0x21
// signature Ljava/lang/Object;Lcom/fztx/service/UserInterface;
// declaration: com/fztx/service/UserService implements com.fztx.service.UserInterface
public class com/fztx/service/UserService implements com/fztx/service/UserInterface {
// compiled from: UserService.java
@Lorg/springframework/stereotype/Component;()
// access flags 0x2
private Lcom/fztx/service/OrderService; orderService
// access flags 0x1
public ()V
L0
LINENUMBER 12 L0
ALOAD 0
INVOKESPECIAL java/lang/Object. ()V
RETURN
L1
LOCALVARIABLE this Lcom/fztx/service/UserService; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x1
public setOrderService(Lcom/fztx/service/OrderService;)V
@Lorg/springframework/beans/factory/annotation/Autowired;()
L0
LINENUMBER 19 L0
ALOAD 0
ALOAD 1
PUTFIELD com/fztx/service/UserService.orderService : Lcom/zhouyu/service/OrderService;
L1
LINENUMBER 20 L1
RETURN
L2
LOCALVARIABLE this Lcom/fztx/service/UserService; L0 L2 0
LOCALVARIABLE orderService Lcom/fztx/service/OrderService; L0 L2 1
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1
public test()V
L0
LINENUMBER 23 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "test123"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 24 L1
RETURN
L2
LOCALVARIABLE this Lcom/fztx/service/UserService; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0x1041
public synthetic bridge setOrderService(Ljava/lang/Object;)V
@Lorg/springframework/beans/factory/annotation/Autowired;()
L0
LINENUMBER 11 L0
ALOAD 0
ALOAD 1
CHECKCAST com/fztx/service/OrderService
INVOKEVIRTUAL com/fztx/service/UserService.setOrderService (Lcom/fztx/service/OrderService;)V
RETURN
L1
LOCALVARIABLE this Lcom/fztx/service/UserService; L0 L1 0
MAXSTACK = 2
MAXLOCALS = 2
}
可以看到在UserSerivce的字节码中有两个setOrderService方法:
并且都是存在@Autowired注解的。
所以在Spring中需要处理这种情况,当遍历到桥接方法时,得找到原方法。
Spring在AutowiredAnnotationBeanPostProcessor的**postProcessProperties()**方法中,会遍历所找到的注入点依次进行注入。时间节点在执行完实例化后(InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation)并且在处理完spring自带的依赖注入之后。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean中:
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
// AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 找注入点(所有被@Autowired注解了的Field或Method)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 依赖注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
首先也是去寻找注入点,但是这个时候可以直接从缓存中取到
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
metadata.inject(bean, beanName, pvs)对注入点进行依赖注入:
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection checkedElements = this.checkedElements;
Collection elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历每个注入点进行依赖注入
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
遍历每个注入点进行依赖注入,注意注入点有属性也有方法,所以循环的InjectedElement会有两个具体的实现类AutowiredFieldElement(属性),AutowiredMethodElement(方法)
所以当执行element.inject(target, beanName, pvs);是对应具体实现类的方法,首先看属性的
AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 根据filed从BeanFactory中查到的匹配的Bean对象
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
// 反射给filed赋值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
resolveFieldValue(field, bean, beanName)方法根据filed从BeanFactory中查到的匹配的Bean对象:
1.将对应的字段封装为DependencyDescriptor对象。
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
2.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象。
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
3.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
// 注册一下beanName依赖了autowiredBeanNames
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
4.利用反射将结果对象赋值给字段。
if (value != null) {
// 反射给filed赋值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
AutowiredMethodElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 如果pvs中已经有当前注入点的值了,则跳过注入
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
如果pvs中已经有当前注入点的值了,则跳过注入
if (checkPropertySkipping(pvs)) {
return;
}
resolveMethodArguments(method, bean, beanName)方法:
1.遍历将对应的方法的参数,将每个参数封装成MethodParameter对象
2.将MethodParameter对象封装为DependencyDescriptor对象
3.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前方法参数所匹配的Bean对象。
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
4.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
5.利用反射将找到的所有结果对象传给当前方法,并执行。
执行完InstantiationAwareBeanPostProcessor.postProcessProperties(@AutoWired,@Resource)之后会执行:
// 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
将BeanDefinition中设置的PropertyValues,去赋值到Bean中。
UserService:
@Service
public class UserService {
@Autowired
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public void sayHi() {
System.out.println(orderService);
}
}
自定义MergedBeanDefinitionPostProcessor实现类:
@Component
public class FztxMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
if ("userService".equals(beanName)) {
beanDefinition.getPropertyValues().add("orderService", new OrderService());
}
}
}
首先在UserService的属性orderService上添加@AutoWired注解,同时我们自定义MergedBeanDefinitionPostProcessor实现类设置BeanDefinition的PropertyValues给orderService赋值,我们通过断点调试一下:
执行完BeanDefinition后置处理,执行AutowiredAnnotationBeanPostProcessor的postProcessProperties方法之前:
BeanDefinition中的PropertyValues设置的orderService是OrderService@1746(自定义MergedBeanDefinitionPostProcessor实现类中new的OrderService)
但我们bean对象中的orderService还是null,此时还没有进行注入点注入
接下来执行AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,@AutoWired注解进行注入:
此时userService对象中的orderService属性值是OrderService@1777(spring容器中的orderservice对象)
接下来执行applyPropertyValues(beanName, mbd, bw, pvs)处理BeanDefinition中设置的PropertyValues,执行完之后:
此时userService对象中的orderService属性值是OrderService@1746,也就是我们自定义自定义MergedBeanDefinitionPostProcessor实现类中new的OrderService
1.BeanDefinition后置处理,执行MergedBeanDefinitionPostProcessor实现类的postProcessMergedBeanDefinition()方法,在这一步会调用AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()方法去寻找注入点(@Autowired、@Value、@Inject)并缓存,同时我们也可以自己定义MergedBeanDefinitionPostProcessor实现类来设置BeanDefinition的PropertyValues(必须要有set方法)
2.处理spring自带的依赖注入,就是上面说的XML或者@Bean设置的的autowire自动注入(byType、byName)--spring标记为过期的,在这一步获取当前Bean中能进行自动注入的属性名,拿到对应的bean,设置到BeanDefinition的PropertyValues(如果之前PropertyValues有某个属性名,这一步则不处理)
3.执行InstantiationAwareBeanPostProcessor实现类的postProcessProperties方法,在这一步会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法对注入点进行注入,会直接给对象中的属性赋值,并不会处理BeanDefinition的PropertyValues,直接返回了;同时也会调用CommonAnnotationBeanPostProcessor的postProcessProperties()方法对@Resource注解进行处理
4.将BeanDefinition中设置的PropertyValues,去赋值给对象中的属性(如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired)
以上是关于Spring中的自动注入(byName,byType)和@Autowired注解的工作原理以及源码分析,下篇文章会分析一下其中的一些方法:BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象;以及@Resource和@Qualifier等注解