一. 介绍
其实 @Autowired 和 Spring AOP 联系不大,但是这个注解和 @Lazy 搭配时,就和 Spring AOP 有千丝万缕的联系了;
由于我对 @Autowired 注解理解的不是很多,所幸一起 debug 看看它里面的流程;
1. demo示例
往 PopulateService 类中注入几个 bean 对象,如下:
@Service
public class PopulateService {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
@Autowired
private Bean01 bean01;
@Autowired
private Bean02 bean02;
public void testPopulate01() {
System.out.println("test populate01...");
}
}
二. @Autowired注入过程
1. getBean()
对 Spring 源码有一定了解的朋友们都知道对 @Autowired 注解处理的逻辑是在 BeanFactory 的 populate() 中的,也就是实例化 bean 对象之后;
我们大致走一下 getBean() 的流程;
1、既然是 BeanFactory 的 populate(),我们得先找到 BeanFactory,BeanFactory 本身是一个接口,它有很多抽象方法,最重要也是最常用的方法就是 getBean(String name),我们直接看它抽象类的AbstractBeanFactory#getBean(String name);
2、我们走到它的 populate();
AbstractBeanFactory#getBean() —>
AbstractBeanFactory#createBean() —>
AbstractAutowireCapableBeanFactory#doCreateBean();
展开 doCreateBean();
// ---------------------- AbstractAutowireCapableBeanFactory ------------------
protected Object doCreateBean(String beanName,
RootBeanDefinition mbd,
@Nullable Object[] args) {
// 1. 实例化 bean 对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 选择合适的构造函数创建 bean 对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException();
}
mbd.postProcessed = true;
}
}
// 创建早期实例对象
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 2. 对刚才创建的 bean 对象执行属性注入,是我们今天的重点关注对象
populateBean(beanName, mbd, instanceWrapper);
// 3. 初始化 bean 对象
// 这个方法里最后会看是否需要生成代理对象
// 如果需要生成代理对象的话会生成代理对象,此时 exposeObject 就已经是代理对象了
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException();
}
if (earlySingletonExposure) {
// ...
}
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException();
}
return exposedObject;
}
我们走到 populate(),看 populate() 的实现;
2. populate()
protected void populateBean(String beanName, RootBeanDefinition mbd,
@Nullable BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 一般这里获得的 pvs 都是 null
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 1. 获取 bean 对象的 autowireMode 值
// 一般我们的 Bean 类都不会有这个值
// 也就是获取的 autowireMode == 0
// 所以 resolvedAutowireMode 不等于 AUTOWIRE_BY_NAME(1),也不等于 AUTOWIRE_BY_TYPE(2)
// 不会走下面 if 里的逻辑
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = bp;
// 2. 执行 InstantiationAwareBeanPostProcessor的postProcessProperties()
// 我们关注和 @Autowired 注解处理有关的 BeanPostProcessor
// CommonAnnotationBeanPostProcessor 是处理 @Resource 注解的
// AutowiredAnnotationBeanPostProcessor 是处理 @Autowired、@Value 等的
// 我们关注 AutowiredAnnotationBeanPostProcessor
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
// ...
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
// ...
}
if (pvs != null) {
// 3. 执行 applyPropertyValues()
// 对于注解形式的 Spring 容器来说,这里的 pvs 虽然不为 null
// 但是 pvs.isEmpty() == true
// 所以这个方法也可以不看
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
我们看 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties();
// -------------------- AutowiredAnnotationBeanPostProcessor ------------------
public PropertyValues postProcessProperties(PropertyValues pvs,
Object bean, String beanName) {
// 1. 构建并获取 @Autowired 注解相关的元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName,bean.getClass(),pvs);
try {
// 2. 根据 @Autowired 注解元数据给 bean 对象进行赋值
// 可以看到其实在 postProcessProperties() 中就已经完成了 bean 对象属性的赋值
metadata.inject(bean, beanName, pvs);
} catch (Throwable ex) {
throw new BeanCreationException();
}
return pvs;
}
这两步都是很重要的操作,我们拆开两部分来看;
2.1 findAutowiringMetadata()
findAutowiringMetadata() 会得到 InjectionMetadata 类对象,我们可以先简单看下 InjectionMetadata 类的结构;
类结构如下:
public class InjectionMetadata {
// 目标类
private final Class<?> targetClass;
// 目标类上的 @Autowired 等注解的元数据集合
private final Collection<InjectedElement> injectedElements;
@Nullable
private volatile Set<InjectedElement> checkedElements;
/**
* 注解的元数据
*/
public abstract static class InjectedElement {
protected final Member member;
protected final boolean isField;
@Nullable
protected final PropertyDescriptor pd;
@Nullable
protected volatile Boolean skip;
protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
this.member = member;
this.isField = (member instanceof Field);
this.pd = pd;
}
}
}
对象结构如下:
可以看到,我们的 populateService 对象有四个 field 属性都被 @Autowired 注解,都被解析为 AutowiredFieldElement 对象;
回到 findAutowiringMetadata();
// -------------------- AutowiredAnnotationBeanPostProcessor ------------------
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz,
@Nullable PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 根据类构造 InjectionMetadata 对象
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
// -------------------- AutowiredAnnotationBeanPostProcessor ------------------
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 1. 获取并构造属性 filed 上的 @Autowired、@Value 等注解的元数据
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
logger.info("Autowired annotation is not supported on static fields: " + field);
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 2. 获取并构造方法 method 上的 @Autowired、@Value 等注解的元数据
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// ...
// 这里的方法体比较绕,我们先不看方法上的 @Autowired、@Value
// 单纯 Bean 对象属性上的 @Autowired、@Value 还是比较好看懂的
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
至此,我们获得了 bean 对象上所有被 @Autowired、@Value 等注解标识的元数据,并存在 InjectionMetadata 对象中;
对于 bean 对象属性上的 @Autowired,会被封装为 AutowiredFieldElement 对象;
2.2 metadata.inject()
我们再看 InjectionMetadata 的 inject();
// ------------------------ InjectionMetadata --------------------------
public void inject(Object target, @Nullable String beanName,
@Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 执行 InjectedElement 的 inject()
// 我们主要看 AutowiredFieldElement 的 inject()
// 其实 AutowiredMethodElement 的 inject() 也是差不多的
element.inject(target, beanName, pvs);
}
}
}
// -------------------------- AutowiredMethodElement ---------------------------
protected void inject(Object bean, @Nullable String beanName,
@Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 1. 根据属性,去 beanFactory 中获取对应的值
// 后面我们会看到,其实是通过我们熟悉的 beanFactory.getBean() 的方式获取的
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames,
typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException();
}
synchronized (this) {
if (!this.cached) {
// ...
}
}
}
if (value != null) {
// 2. 当从 beanFactory 中获取到了属性对应的值时
// 通过反射将属性值赋值进 bean 中
// 这里可以看到 makeAccessible(),解释了为啥Bean里的私有属性也可以被@Autowired赋值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
我们关注 beanFactory.resolveDependency(),Spring 容器中功能最强大的 beanFactory 是 DefaultListableBeanFactory,我们点进它的 resolveDependency();
public Object resolveDependency(DependencyDescriptor descriptor,
@Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider();
}
else {
// 1. 如果当前 @Autowired 属性同时被 @Lazy 注解
// 这里 result 会被构造为代理类 proxy 对象!!!
// 我们为什么要在 AOP 中讲 @Autowired,主要是看这块逻辑
// 如果没有被 @Lazy 注解,result == null,走下述逻辑
Object result = getAutowireCandidateResolver()
.getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
// 2. 没有被 @Lazy 注解的情况,走下述逻辑
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName,
autowiredBeanNames, typeConverter);
}
return result;
}
}
2.2.1 @Lazy注解生成代理对象
我们看 getLazyResolutionProxyIfNecessary() 会生成什么;
// ------------------ ContextAnnotationAutowireCandidateResolver ----------------
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor,
@Nullable String beanName) {
// 如果没有 @Lazy 注解,返回 null
// 如果有 @Lazy 注解,调用 buildLazyResolutionProxy() 生成并返回代理对象
return (isLazy(descriptor) ?
buildLazyResolutionProxy(descriptor, beanName) : null);
}
// ------------------ ContextAnnotationAutowireCandidateResolver ----------------
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor,
final @Nullable String beanName) {
BeanFactory beanFactory = getBeanFactory();
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
// 1. 创建一个 TargetSource
// 这里的 TargetSource 不是 SimpleTargetSource,而是自定义的 TargetSource 对象
// 它重写了 getTarget()
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
// 1.1 beanFactory.doResolveDependency() 后面还会讲
// 这里通俗讲就是 beanFactory.getBean() 从 bean 容器中获取 bean 对象
Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
if (target == null) {
Class<?> type = getTargetClass();
if (Map.class == type) {
return Collections.emptyMap();
}
else if (List.class == type) {
return Collections.emptyList();
}
else if (Set.class == type || Collection.class == type) {
return Collections.emptySet();
}
throw new NoSuchBeanDefinitionException();
}
if (autowiredBeanNames != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (dlbf.containsBean(autowiredBeanName)) {
dlbf.registerDependentBean(autowiredBeanName, beanName);
}
}
}
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
// 2. 创建 ProxyFactory 对象
ProxyFactory pf = new ProxyFactory();
// 设置 TargetSource 对象
pf.setTargetSource(ts);
Class<?> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
// 3. 生成代理类对象
return pf.getProxy(dlbf.getBeanClassLoader());
}
可以看到,这里通过 ProxyFactory 生成了代理类对象,对比我们 AOP 创建的代理类,会发现这个代理类对象没有任何的 Advisors 和 Advices,它的核心在于 TargetSource 不再是 SimpleTargetSource;
- SimpleTargetSource#getTarget() 直接返回 bean 对象;
- 这里的 TargetSource#getTarget() 去 beanFactory 中调用 beanFactory.getBean() 得到真正的 bean 对象;
当执行到代理类对象的方法时,会调用到 DynamicAdvisedInterceptor#intercept(),我们重温一下该方法应用于 @Lazy 时的逻辑,以不同的视角看 intercept();
// ------------------------- DynamicAdvisedInterceptor -------------------------
private static class DynamicAdvisedInterceptor implements MethodInterceptor {
private final AdvisedSupport advised;
// 构造方法,传入 AdvisedSupport 类对象,一般是我们的 ProxyFactory 对象
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
// 1. 获取到 advised 的 targetSource 对象
TargetSource targetSource = this.advised.getTargetSource();
try {
// 是否将代理类对象暴露到 AopContext 线程变量上
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 2. 执行 targetSource 的 getTarget()
// 对于 @Lazy 注解的代理类对象,这里会从 beanFactory 获得真正的 bean 实例对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 3. 根据方法和目标类获取匹配的 advisors
// 从上文我们说到 @Lazy 的 ProxyFactory 没有任何 advisors 和 advices
// 所以这里得到的 chain 一定是空的
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 3.1 如果没有符合条件的 advisors,反射调用目标方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method,
args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
这也是为什么 @Lazy 能解决循环依赖问题,因为 Spring 容器会在 @Lazy 处放入代理对象,只有执行到了这个对象的方法时才会从 Spring 容器中真正加载这个 bean 对象;
值得一提的是,如果此时 getTarget() 获取的 bean 还是一个代理类对象,就进入了喜闻乐见的代理套娃场景啦,感兴趣可以尝试构造看看;
2.2.2 doResolveDependency()
属性注入的重头戏,我们看下这个 doResolveDependency() 在干啥;
这个方法也是挺绕的,我们看主流程,后面有空在细看;
// ------------------------ DefaultListableBeanFactory -------------------------
public Object doResolveDependency(DependencyDescriptor descriptor,
@Nullable String beanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 处理 @Value 注解的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
// ...
}
// 对集合类型进行处理,如 Array、Collection、Map
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 查找所有类型为 type 的实例
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
// 如果没有找到,且 required == true,抛出异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(),
descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 如果 type 的实例不止一个,需要筛选出一个
if (matchingBeans.size() > 1) {
// 按以下顺序筛选
// 1. 挑选出被标识为 primary 的 bean
// 2. 挑选标识了 @Priority,且先级级最高的 bean
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(),
matchingBeans);
} else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
Map.Entry<String, Object> entry =
matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 核心方法!!!
// 当 @Autowired 注解的属性是类时
// 调用 descriptor.resolveCandidate() 获取值
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
// 如果没有找到,且 required == true,抛出异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(),
descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException();
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
// -------------------------- DependencyDescriptor --------------------------
public Object resolveCandidate(String beanName, Class<?> requiredType,
BeanFactory beanFactory) {
// 调用并返回 beanFactory.getBean()
return beanFactory.getBean(beanName);
}
可以看到,最终调用了 beanFactory.getBean(beanName) 获得属性对应的值,至此,@Autowired 值注入完成;