Spring 5.x Source trip twenty-nine getBean Detailed fourteen populateBean two
autowireResource automatic assembly Resource annotation object
Here is mainly dependent description according to parse the plant, ultimately call getBean(String name, Class<T> requiredType)
the method, after the last re-registration to get dependent on the mapping. In fact, there is this resolveBeanByName
, looks like the name first, in fact, will get the type of.
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)) {//不包含依赖对象,或者依赖对象的bean定义,只能通过解析类型去处理
autowiredBeanNames = new LinkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {//获取依赖对象,里面就是getBean
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);//装配好的bean名字
}
}
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;
}
AutowiredAnnotationBeanPostProcessor的postProcessProperties
And here in front of like, this is the template.
@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;
}
InjectionMetadata的inject
There is also:
AutowiredFieldElement的inject
Finally, but AutowiredFieldElement
the type of method, front ResourceElement
, they are InjectedElement
subclasses, ResourceElement
the handling properties and methods put together judgment processing, automatic assembly AutowiredFieldElement
and AutowiredMethodElement
are handled separately.
If you have a cache dependency description, it will be described in terms of cache dependencies to resolve dependent objects, or otherwise perform bean
the factory resolveDependency
, but this time will pass TypeConverter
type, and then parse it out if it is required
, it is placed in the cache, and register dependency information, if automatic assembly of bean
only one, created ShortcutDependencyDescriptor
and placed in the cache.
@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);
}
}
AutowiredAnnotationBeanPostProcessor的resolvedCachedArgument
Checking the cache is not dependent of the type described, it is then extracted data, and then resolve dependencies.
@Nullable
private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor) {
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
Assert.state(this.beanFactory != null, "No BeanFactory available");
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
}
else {
return cachedArgument;
}
}
In fact, no matter what kind of injection of notes, the principle is the same, it should be based on the name and type of container to find other similar look yourself just fine.
Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.