AutowiredAnnotationBeanPostProcessor
文章目录
- 概述
- 源码解析
- 加载到容器
- 构造方法
- postProcessMergedBeanDefinition 方法
- findAutowiringMetadata 方法
- postProcessProperties 方法
- InjectionMetadata 注入元信息对象
- AutowiredFieldElement
- AutowiredMethodElement
概述
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
,主要处理@Autowired
和@Value
注解进行依赖注入。
可以看到AutowiredAnnotationBeanPostProcessor
实现了MergedBeanDefinitionPostProcessor
和InstantiationAwareBeanPostProcessor
两个接口
源码解析
加载到容器
在 XML 文件中的<context:component-scan />
标签的处理过程中,会底层借助于ClassPathBeanDefinitionScanner
扫描器,去扫描指定路径下符合条件(@Component
注解)的BeanDefinition
们,关于@ComponentScan
注解的解析也是借助于这个扫描器实现的。扫描过程如下:
// ClassPathBeanDefinitionScanner.java
public int scan(String... basePackages) {
// <1> 获取扫描前的 BeanDefinition 数量
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// <2> 进行扫描,将过滤出来的所有的 .class 文件生成对应的 BeanDefinition 并注册
doScan(basePackages);
// Register annotation config processors, if necessary.
// <3> 如果 `includeAnnotationConfig` 为 `true`(默认),则注册几个关于注解的 PostProcessor 处理器(关键)
// 在其他地方也会注册,内部会进行判断,已注册的处理器不会再注册
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// <4> 返回本次扫描注册的 BeanDefinition 数量
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
在第<3>
步会调用AnnotationConfigUtils
的registerAnnotationConfigProcessors(BeanDefinitionRegistry)
方法,如下:
// AnnotationConfigUtils.java
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 处理 Spring 应用上下文中的配置类
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 处理 @Autowired 以及 @Value 注解
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// (条件激活)处理 JSR-250 注解 @Resource,如 @PostConstruct、@PreDestroy 等
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Processor 对象(条件激活)处理 JPA 注解场景
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 处理标注 @EventListener 的 Spring 事件监听方法
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 用于 @EventListener 标注的事件监听方法构建成 ApplicationListener 对象
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
在这个方法中可以看到会注册AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
两个处理器,然后在 Spring 应用上下文刷新阶段会将其初始化并添加至AbstractBeanFactory
的beanPostProcessors
集合中,那么接下来我们先来分析这两个处理器
构造方法
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
/**
* 保存需要处理的注解
*/
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
private String requiredParameterName = "required";
private boolean requiredParameterValue = true;
private int order = Ordered.LOWEST_PRECEDENCE - 2;
@Nullable
private ConfigurableListableBeanFactory beanFactory;
private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
/**
* 缓存需要注入的字段元信息
*/
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
/**
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
* standard {@link Autowired @Autowired} annotation.
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available.
*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
}
可以看到会添加@Autowired
和@Value
两个注解,如果存在JSR-330
的javax.inject.Inject
注解,也是支持的。
postProcessMergedBeanDefinition 方法
postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
方法,找到@Autowired
和@Value
注解标注的字段(或方法)的元信息,如下:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 找到这个 Bean 所有需要注入的属性(@Autowired 或者 @Value 注解)
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
直接调用findAutowiringMetadata(...)
方法获取这个 Bean 的注入元信息对象
findAutowiringMetadata 方法
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
// 生成一个缓存 Key
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// 先尝试从缓存中获取
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);
}
// 构建一个需要注入的元信息对象
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
首先尝试从缓存中获取这个 Bean 对应的注入元信息对象,没有找到的话则调用buildAutowiringMetadata(final Class<?> clazz)
构建一个,然后再放入缓存中
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
// <1> 创建 `currElements` 集合,用于保存 @Autowired、@Value 注解标注的字段
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// <2> 遍历这个 Class 对象的所有字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// <2.1> 找到该字段的 @Autowired 或者 @Value 注解,返回 `ann` 对象,没有的话返回空对象,则直接跳过不进行下面的操作
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
// <2.2> 进行过滤,static 修饰的字段不进行注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// <2.3> 获取注解中的 `required` 配置
boolean required = determineRequiredStatus(ann);
// <2.4> 根据该字段和 `required` 构建一个 AutowiredFieldElement 对象,添加至 `currElements`
currElements.add(new AutowiredFieldElement(field, required));
}
});
// <3> 遍历这个 Class 对象的所有方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// <3.1> 尝试找到这个方法的桥接方法,没有的话就是本身这个方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
// <3.2> 如果是桥接方法则直接跳过
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// <3.3> 找到该方法的 @Autowired 或者 @Value 注解,返回 `ann` 对象,没有的话返回空对象,则直接跳过不进行下面的操作
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// <3.4> 进行过滤,static 修饰的方法不进行注入
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// <3.5> 获取注解中的 `required` 配置
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// <3.6> 构建一个 AutowiredMethodElement 对象,添加至 `currElements`
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
// <4> 找到父类,循环遍历
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// <5> 根据从这个 Bean 解析出来的所有 InjectedElement 对象生成一个 InjectionMetadata 注入元信息对象,并返回
return new InjectionMetadata(clazz, elements);
}
postProcessProperties 方法
postProcessProperties(PropertyValues pvs, Object bean, String beanName)
方法,根据@Autowired
和@Value
注解标注的字段(或方法)的元信息进行依赖注入,如下:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 找到这个 Bean 的注入元信息对象
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 注入元信息对象
org.springframework.beans.factory.annotation.InjectionMetadata
,某个 Bean 的注入元信息对象
public class InjectionMetadata {
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
/**
* 需要注入的字段(或方法)的元信息
*/
private final Collection<InjectedElement> injectedElements;
@Nullable
private volatile Set<InjectedElement> checkedElements;
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
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) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
}
可以看到注入方法非常简单,就是遍历所有的InjectedElement
对象,调用他们的inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs)
方法
AutowiredFieldElement
AutowiredAnnotationBeanPostProcessor
的私有内部类,注入字段对象,如下:
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
/** 是否必须 */
private final boolean required;
/** 是否缓存起来了 */
private volatile boolean cached = false;
/** 缓存的对象 */
@Nullable
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, null);
this.required = required;
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// <1> 获取 `field` 字段
Field field = (Field) this.member;
Object value;
// <2> 如果进行缓存了,则尝试从缓存中获取
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
// <3> 否则,开始进行解析
else {
// <3.1> 创建一个依赖注入描述器 `desc`
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 {
/**
* <3.2> 通过 {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency} 方法
* 找到这个字段对应的 Bean(们)
*/
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// <3.3> 和缓存相关,如果有必要则将本次找到的注入对象缓存起来,避免下次再进行解析
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// <4> 如果获取到该字段对应的对象,则进行属性赋值(依赖注入)
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
AutowiredMethodElement
AutowiredAnnotationBeanPostProcessor
的私有内部类,注入方法对象,如下:
private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
/** 是否必须 */
private final boolean required;
/** 是否缓存起来了 */
private volatile boolean cached = false;
/** 缓存的方法参数对象 */
@Nullable
private volatile Object[] cachedMethodArguments;
public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
super(method, pd);
this.required = required;
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
// <1> 获取 `method` 方法
Method method = (Method) this.member;
// <2> 如果进行缓存了,则尝试从缓存中获取方法参数对象
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
// <3> 否则,开始进行解析
else {
// <3.1> 获取方法的参数类型集合 `paramTypes`,根据参数位置确定参数
Class<?>[] paramTypes = method.getParameterTypes();
arguments = new Object[paramTypes.length];
// <3.2> 构建一个依赖注入描述器数组 `descriptors`,用于保存后续创建的对象
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
// <3.3> 根据参数顺序遍历该方法的参数
for (int i = 0; i < arguments.length; i++) {
// <3.3.1> 为第 `i` 个方法参数创建一个 MethodParameter 对象
MethodParameter methodParam = new MethodParameter(method, i);
// <3.3.2> 创建依赖描述器 `currDesc`,并添加至 `descriptors` 数组
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
/**
* <3.3.3> 通过 {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency} 方法
* 找到这个方法参数对应的 Bean(们)
*/
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
// <3.4> 和缓存相关,如果有必要则将本次找到的方法参数对象缓存起来,避免下次再进行解析
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
Object[] cachedMethodArguments = new Object[paramTypes.length];
System.arraycopy(descriptors, 0, cachedMethodArguments, 0, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == paramTypes.length) {
Iterator<String> it = autowiredBeans.iterator();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
// <4> 如果找到该方法的参数(们),则进行属性赋值(依赖注入)
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
// 通过反射机制调用该方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
核心就是通过DefaultListableBeanFactory#resolveDependency(...
方法找到方法参数对应的 Bean,具体查看源码解析:
DefaultListableBeanFactory