在spring中,我们都用过@Autowire, @Resource, @Inject, @Value这几个注解,可是我们都知道这些注解标注的属性值是怎么装配到bean中的么?
问题:首先我们看看这几个注解的不同?
@Value:将配置文件中,或者环境中的值装配到bean属性上
@Autowire与@Inject都是都是由AutowiredAnnotationBeanPostProcessor进行处理的,不同在于@Autowire有required属性,而@Inject没有
@Autowire与@Resource由不同的后置处理器进行处理,@Resource由CommonAnnotationBeanPostProcessor进行处理,还有@Autowrie属于spring注解,而@Resource和@Inject属于java注解
问题:如何证明@Value, @Inject, @Autowire由AutowiredAnnotationBeanPostProcessor进行处理,而@Resource由CommonAnnotationBeanPostProcessor处理
根据CommonAnnotationBeanPostProcessor类的静态代码块我们可以知道,在类加载的时候就将将Resource.class添加到了resourceAnnotationTypes中了
而在AutowiredAnnotationBeanPostProcessor类的构造方法中,也是将Value, Inject, Autowire添加到了autowiredAnnotationTypes中了
在这两个类中这两个属性在后续属性装配是非常重要
//CommonAnnotationBeanPostProcessor 静态代码块
static {
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> clazz = (Class<? extends Annotation>)
ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
webServiceRefClass = clazz;
}
catch (ClassNotFoundException ex) {
webServiceRefClass = null;
}
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> clazz = (Class<? extends Annotation>)
ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
ejbRefClass = clazz;
}
catch (ClassNotFoundException ex) {
ejbRefClass = null;
}
//************************************************
//**重点
//默认初始化,添加Resource.class到resourceAnnotationTypes中
resourceAnnotationTypes.add(Resource.class);
if (webServiceRefClass != null) {
resourceAnnotationTypes.add(webServiceRefClass);
}
if (ejbRefClass != null) {
resourceAnnotationTypes.add(ejbRefClass);
}
}
//AutowiredAnnotationBeanPostProcessor构造方法
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.
}
}
问题:属性装配发生在什么时候?
读取spring bean创建的源码我们可以找到doCreateBean()这样一个方法,该方法就是执行bean创建的方法,但是bean的创建过程非常复杂,并非如下这段代码可以说的清楚的,这里只是为了解属性装配发生在什么时候,所有bean的实例化过程不在此说明
我们可以看到在bean创建成功后,会调用populateBean(beanName, mbd, instanceWrapper);这样一个方法,这个方法就是进行属性装配的方法
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
//首先从缓存中获取,同时删除缓存中的对象
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//获取bean包装实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//申请合并BeanDefinition后置处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//原来getSingleton()方法中earlySingletonObjects数据在这里设置的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性添加,给实例对象填充属性
populateBean(beanName, mbd, instanceWrapper);
//初始化bean, 也就是生命周期回到,@PostConstruct,InitializingBean SmartInitializingSingleton
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//从单例池中获取对象,如果单例池中不存在实例对象,
//那么就从earlySingletonObjects中查找
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
//需要研究???似乎是解决循环依赖的
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
//注册对象销毁,对象销毁时需要调用的方法也是很在这个地方进行注册的(内部有方法需要好好看看)
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
问题:我们知道了@Autowire, @Value, @Inject由AutowiredAnnotationBeanPostProcessor处理,@Resource由CommonAnnotationBeanPostProcessor处理,spring是怎么知道那些属性需要进行装配,又是如何还实现的?
要完成属性装配,首先我们需要解决的一个问题是要知道那些属性需要装配,这个时候最开始说到的那些注解已经那两个类(@Resource, @Inject, @Autowire, @Value)[CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor]就要起作用了
那么spring是如何查找这些需要装配的属性的呢?依旧查看上边的这个方法doCreateBean();这个 方法中有applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);这样一个方法调用,spring就是通过这里后置处理器进行判断的,查看看这个方法内部实现,方法内部调用了后置处理器的bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);方法,那么在CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor中这两个方法的实现分别是?
首先Spring拿到类的所有属性,然后查到这里属性上标注的注解,在与CommonAnnotationBeanPostProcessor/AutowiredAnnotationBeanPostProcessor中对应的注解比对,如果在后置处理中认定注解,那么对应的这个属性就需要进行属性装配
在AutowiredAnnotationBeanPostProcessor中判断是,只要找到一个就立马返回,无需后续在次判断
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
//----------------------------------------------------------------------
//AutowiredAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//查找需要装配的属性元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
//----------------------------------------------------------------------
//查找需要装配的属性元数据,最后查找出来的这些属性会被放到injectionMetadataCache中,而在后续进行实际装配时,也会从这里边查找需要的属性名称
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
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;
}
//----------------------------------------------------------------------
//构建属性装配元数据
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//查找属性上中标注的自动装配注解,@Value, @Inject, @Autowire, 找到一个就会立即返回
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//判断属性装配的必要性
//如:@Autowire(required=false)则表示在找不到合适的属性值时,就不进行属性装配
//否则如果属性装配必须时,找不到合适的属性值将会抛出异常
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
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);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
//----------------------------------------------------------------------
//查找属性装配注解,@Value, @Inject, @Autowire
//只要找到其中一个就立马返回
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao, SearchStrategy.INHERITED_ANNOTATIONS);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
//
//
//
//CommonAnnotationBeanPostProcessor中属性装配元数据构建方法
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//查找需要进行装配的属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
}
currElements.add(new WebServiceRefElement(field, field, null));
}
else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static fields");
}
currElements.add(new EjbRefElement(field, field, null));
}
else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
//查找需要进行装配的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
}
else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new EjbRefElement(method, bridgedMethod, pd));
}
else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
问题:既然知道了哪些属性需要进行装配,那么spring是如何拿到这些需要装配的属性值的,又是如何将他们装配上的
终于到属性装配这一步了,我们看看populateBean()方法的实现,这个方法一般情况下前边一大截都是没用,因为在一般情况下pvs都是空的,还有我们需要注意的是,在真正进行属性装配前,会执行InstantiationAwareBeanPostProcessor 后置处理器的postProcessAfterInstantiation()方法,如果我们想在自己实现某些特殊属性装配,这是spring为我们提供一个拓展点,不过需要注意的是,这个方法需要返回ture,如果其中某一个后置处理器的该方法返回flase,那么后续的装配也就不会执行了
实际真正执行装配工作也是通过后置处理器进行的,所有在spring中,后置处理器是一个非常重要的概念,基本所有的工作都是通过后置处理器完成。ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);这个InstantiationAwareBeanPostProcessor 后置处理器的方法调用就是完成装配的核心,深入到这两个后置处理器方法内部我们知道,获取到metadata后执行inject()方法,完成属性注入
根据代码可以知道,@Resource通过名称查找属性值,而非@Resource的情况下,
* 首先从@Value推荐池中获取
* 然后根据类型查找
* 如果根据类型能查找到多个值,那么选择Primary, 如果没有或者存在多个Primary
* 则选这Priority,如果没有或者存在多个最高,则在这些候选项中根据名称查找
* 如果还是查不到,再根据名称再重新获取一遍
*
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* 进行bean属性填充
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
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 beanfactorypostprocessor are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//拿出所有的beanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//过滤InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//如果其中一个执行结果返回false,后面的postProcessor就无需执行了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//注意, spring要是没有提供InstantiationAwareBeanPostProcessor,或者所提供的InstantiationAwareBeanPostProcessor
//postProcessAfterInstantiation方法都返回存在false,必须要保证所有的后置处理器都正常得到了执行,那么说明后续无需继续执行
//那么就说明使用自定义的后置处理器进行属性注入即可
if (!continueWithPropertyPopulation) {
return;
}
//拿出属性
//已有的这些应该是通过BeanFactoryPostProcessor进行填充的
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//获取自动注入模型/NO/ByName/ByType/ByConstructor/AutoDec
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
//通过名称或者类型自动注入处理
//需要处理通过注解或者xml配置的部分
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
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;
}
//判断是否存在InstantiationAwareBeanPostProcessors
//如果存在, 在对象销毁时,会执行一些特殊的事情
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()) {
//过滤出所有的InstantiationAwareBeanPostProcessor
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;
}
}
}
//属性检查
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
//-----------------------------------------------------------------
//CommonAnnotationBeanPostProcessor,进行属性装配的方法
//这里的findResourceMetadata()就是之前我们分析获取元数据的方法
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//获取需要装配的属性元数据
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
//进行属性装配
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
/**
* @Autowire, @Value, @Inject属性装配执行后置处理器方法
* AutowiredAnnotationBeanPostProcessor
* @param pvs
* @param bean
* @param beanName
* @return
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
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;
}
//属性装配
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);
}
}
}
@Override
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 {
//拿取需要装配的属性值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
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;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
问题:都说@Resource()是根据名称进行属性注入,怎么证明?
我们刚才看了metadata.inject()方法,接着往这个方法深入,我们会找到autowireResource()这个方法的调用,这个方法内部resource = factory.getBean(name, element.lookupType);有这么一段,证明了我们的问题
- resource = beanFactory.resolveBeanByName(name, descriptor);
/**
* Obtain a resource object for the given name and type through autowiring
* based on the given factory.
* @param factory the factory to autowire against
* @param element the descriptor for the annotated field/method
* @param requestingBeanName the name of the requesting bean
* @return the resource object (never {@code null})
* @throws NoSuchBeanDefinitionException if no corresponding target resource found
*/
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
Object resource;
Set<String> autowiredBeanNames;
String name = element.name;
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
for (String autowiredBeanName : autowiredBeanNames) {
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
}
return resource;
}
问题:@Autowire是使用类型注入?
都说@Autowire是首先按照类型查找,如果查到有多个候选项,判断是否有Primary, 如果没有判断是否有优先级最大的,如果优先级都一样,再按照名字查找,如果在多个候选项中根据名称确定不了,还会通过名称直接重新获取一遍,如果还是查不到,但是有多个候选,那么抛出有候选项不唯一的异常,如果找不到这种类型的bean,所以网上的说明都不完全,那么如何证明呢,看源码,其实这个说法还不完全,最先还要去查找@Value推荐池中能不能找到属性,如果找不到才获取bean
/**
* 获取需要装配的属性值
* 首先从@Value推荐池中获取
* 然后根据类型查找
* 如果根据类型能查找到多个值,那么选择Primary, 如果没有或者存在多个Primary
* 则选这Priority,如果没有或者存在多个最高,则在这些候选项中根据名称查找
* 如果还是查不到,再根据名称再重新获取一遍
*
* 如果通过类型查找出多个,但是确定不了唯一,则会报不唯一异常
* 如果找不到一个符合条件的,则会报找不到异常
* @param descriptor
* @param beanName
* @param autowiredBeanNames
* @param typeConverter
* @return
* @throws BeansException
*/
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
//首先获取@Vaule推荐值
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//查找候选项 通过类型查找
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//存在多个候选项是,首先悬着Primary, 然后选择最高权重,最后选择名称
if (matchingBeans.size() > 1) {
//判断在存在多个候选项的时候,该选择哪一个bean
//首先判断Primary,如果没有Primary或者存在多个Primary则继续
// 判断Priority,如果没有或存在多个相同的Priority,返回
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
//下边根据拿到的名称到容器中获取bean
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
/**
* Determine the autowire candidate in the given set of beans.
* 判断在存在多个候选项的时候,该选择哪一个bean
* 首先判断Primary,如果没有Primary或者存在多个Primary则继续
* 判断Priority,如果没有或存在多个相同的Priority,返回
* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
* @param candidates a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param descriptor the target dependency to match against
* @return the name of the autowire candidate, or {@code null} if none found
*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {//存在多个候选项是,判断是否有Primary存在
return primaryCandidate;
}//选择权重最高的
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();//根据名称匹配
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
问题:都在议论spring自动注入模型,那么到底使用了那种注入模型?
spring默认不采用任何注入模型
public int getResolvedAutowireMode() {
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// Work out whether to apply setter autowiring or constructor autowiring.
// If it has a no-arg constructor it's deemed to be setter autowiring,
// otherwise we'll try constructor autowiring.
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
//默认情况
//默认不采取自动注入
//private int autowireMode = AUTOWIRE_NO;
return this.autowireMode;
}
}