Spring source (nine) @Autowired annotation implementation principles (Spring Bean automatic assembly)

Implementation @Autowired notes, in fact, Spring Bean's automated assembly process. @Autowired comment section by looking at the source code, we can see @Autowired is achieved by AutowiredAnnotationBeanPostProcessor post-processor implemented.

AutowiredAnnotationBeanPostProcessor 类图


PriorityOrdered: Verify that the postprocessor AutowiredAnnotationBeanPostProcessor priority
BeanFactoryAware: AutowiredAnnotationBeanPostProcessor that can be acquired directly by the BeanFactory Bean container
BeanPostProcessor: postprocessor Bean performed before and after the initialization
setting attribute values before and after the instantiation Bean and Bean: InstantiationAwareBeanPostProcessor postprocessor executed
SmartInstantiationAwareBeanPostProcessor: Bean instantiated intelligent post-processor, such as the prediction and confirmation of the type constructors Bean Bean and the like.
MergedBeanDefinitionPostProcessor: Bean of consolidation definition information.
Automatic assembly prior to analysis we first introduce above these post-processor.

Post-processor introduces
the BeanPostProcessor
the BeanPostProcessor there are two methods, postProcessBeforeInitialization and postProcessAfterInitialization. They are performed (e.g. InitializingBean the afterPropertiesSet method before customizing init-method method or after), at this time, the property value of the bean has been filled completed before any bean initialization callback or after, and bean instance we return may have the original instance is the type of packaging. Such as returning a FactoryBean.

InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor inherited from BeanPostProcessor interface. The main multi provides the following three methods.

postProcessBeforeInstantiation
which is before calling the target object is instantiated Bean, Bean returned object can delegate object, so as to effectively prevent the default target Bean is instantiated.

Object resolveBeforeInstantiation protected (String beanName, RootBeanDefinition MBD) {
Object bean = null;
IF (! Boolean.FALSE.equals (mbd.beforeInstantiationResolved)) {
// the Make the Sure bean class IS AT Actually resolved the this Point.
IF (mbd.isSynthetic! () && hasInstantiationAwareBeanPostProcessors ()) {
Class targetType = determineTargetType (beanName, MBD) <?>;
! IF (targetType = null) {
bean = applyBeanPostProcessorsBeforeInstantiation (targetType, beanName);
! IF (bean = null) {
// If this method returns a non-null object, Bean creation process will be short-circuited.
// only application for further processing from the postProcessAfterInitialization callback configured BeanPostProcessors
the bean = applyBeanPostProcessorsAfterInitialization (the bean, the beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

Object applyBeanPostProcessorsBeforeInstantiation protected (Class beanClass, the beanName String <?>) {
for (the BeanPostProcessor BP: getBeanPostProcessors ()) {
IF (BP InstantiationAwareBeanPostProcessor the instanceof) {
InstantiationAwareBeanPostProcessor IBP = (InstantiationAwareBeanPostProcessor) BP;
after Bean instance before execution of the target object // processing method
Object ibp.postProcessBeforeInstantiation Result = (beanClass, the beanName);
IF (! Result = null) {
return Result;
}
}
}
return null;
}
follow source we can see, if this method returns a non-null object, Bean will be the process of creating a short circuit. The only further processing application from the configured BeanPostProcessors of postProcessAfterInitialization callback.

postProcessAfterInstantiation
the method is performed by a constructor or factory method after instantiating the bean properties but Spring filled (through explicit or automatic assembly property) occurs before performing the operation. This is performed over the custom field injection given bean instance callback Spring before the start of automatic assembly. If this method returns false, then it will perform the subsequent block InstantiationAwareBeanPostProcessor post-processor, and execution logic prevents subsequent filling property.

postProcessPropertyValues
factory applied to a given attribute value set before bean, after they are processed. Allow checked whether all the dependencies, for example, based on the "Required" bean property annotations on setters. Also allows the replacement property values to be applied, usually by creating a new instance of MutablePropertyValues based on the original PropertyValues, add or delete certain values to achieve.

SmartInstantiationAwareBeanPostProcessor
Smart Bean instantiation of the processor, which offers three methods.

predictBeanType
prediction from postProcessBeforeInstantiation callback handler returns the final type of the bean.

determineCandidateConstructors
determined using a constructor to instantiate the Bean.

getEarlyBeanReference
get early exposure Bean references, early exposure Bean is instantiated only completed, not yet completed property assignment and initialization of Bean.

MergedBeanDefinitionPostProcessor
postProcessMergedBeanDefinition
post-processing method combined Bean definition information, the method is called before the set value after the Bean instantiated.

Automated assembly to achieve
find the elements required automatic assembly
AutowiredAnnotationBeanPostProcessor post-processor is mainly responsible for implementing automated assembly of added @Autowired and @Value annotation elements. So to find the elements that need automated assembly, in fact, resolved to @Autowired and @Value annotations.

AutowiredAnnotationBeanPostProcessor post-processor to identify the need for automatic mounting element is realized in this method MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition call link as follows:

doWith:445, AutowiredAnnotationBeanPostProcessor$2 (org.springframework.beans.factory.annotation)
doWithLocalFields:657, ReflectionUtils (org.springframework.util)
buildAutowiringMetadata:433, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
findAutowiringMetadata:412, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
postProcessMergedBeanDefinition:235, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
applyMergedBeanDefinitionPostProcessors:1000, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:523, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>: 84, AnnotationConfigApplicationContext ( org.springframework.context.annotation)
we can see from the link, find the elements required automatic assembly is achieved in findAutowiringMetadata method, the method will be to call buildAutowiringMetadata way to build metadata information . If the annotations are loaded on the properties it will be encapsulated in an object AutowiredFieldElement; annotation if applied to the method, the element is encapsulated into AutowiredMethodElement objects. The method herein inject two objects will be finalized injecting property value, the main difference is the use of a reflective injection value is not the same. Source as follows:

private InjectionMetadata buildAutowiringMetadata(final Class<www.yongshenyul.com > clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;

{do
// store metadata information we find
Final the LinkedList <InjectionMetadata.InjectedElement> = currElements
new new the LinkedList <InjectionMetadata.InjectedElement> (www.yuanygw.com);

// find all Class Field corresponding to the object by reflection
ReflectionUtils.doWithLocalFields (targetClass, new new ReflectionUtils.FieldCallback () {
@Override
public void doWith (field, field) throws an IllegalArgumentException, IllegalAccessException {
// find all the annotation information by reflection on the field, and determines whether there is @Autowired and @Value annotations, if sealed into the field on the object AutowiredFieldElement
AnnotationAttributes Ann findAutowiredAnnotation = (field);
IF (! Ann = null) {
IF (Modifier.isStatic (field.getModifiers ())) {
IF (logger.isWarnEnabled (www.baichuangyule.cn) ) {
logger.warn ( "Annotation Autowired is Not Supported IS ON static Fields:" Field +);
}
return;
}
Boolean = determineRequiredStatus required (Ann) ;,
// AutowiredFieldElement sealed into the field object into the cache and
currElements.add (new new AutowiredFieldElement (Field, required));
}
}
});

// Method to identify all reflected by the object corresponding to Class
ReflectionUtils.doWithLocalMethods (www.jintianxuesha.com targetClass, new new ReflectionUtils.MethodCallback () {
@Override
public void doWith (Method Method) throws an IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = www.yuchengyuledl BridgeMethodResolver.findBridgedMethod .com (Method);
(! BridgeMethodResolver.isVisibilityBridgeMethodPair (Method, bridgedMethod)) IF {
return;
}
// all annotation information by reflection on the field to find, and determines whether there is @Autowired and @Value annotations, if there are sealed into the field on the object AutowiredMethodElement
AnnotationAttributes = Ann findAutowiredAnnotation (bridgedMethod);
IF (! = null && Ann method.equals (ClassUtils.getMostSpecificMethod (Method, clazz))) {
IF (Modifier.isStatic (method.getModifiers () )) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 将该字段封成AutowiredMethodElement对象
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
});

elements.addAll (0, currElements);
targetClass targetClass.getSuperclass = ();
}
// loop processing elements need parent autowiring
the while (www.qjljdgt.cn targetClass = null && targetClass = Object.class!!);
/ / element will be automatically assembled into a package InjectionMetadata object definition and merged into Bean
return new new InjectionMetadata (clazz, elements);
}
find require automatic assembly process:

The Class object, all obtained by reflection and `` `Method```` Field objects
acquired Field and annotations on the Method by reflection, and determines whether there is @Autowired @Value annotation and
the annotation of the Field @Autowired and @Value Method and encapsulated into AutowiredFieldElement AutowiredMethodElement objects and wait for the next automatic assembly.
Loop process requires the parent element of the automatic assembling
will be automatically assemble elements into a package InjectionMetadata objects, and finally merge into externallyManagedConfigMembers Bean attributes defined
injecting property values
AutowiredAnnotationBeanPostProcessor postprocessor injection property value is achieved in postProcessPropertyValues process. Source as follows:

Inject void public (Object target, String the beanName, the PropertyValues PVS) throws the Throwable {
// Get metadata information to be automatically fitted (here, it is taken buffer)
Collection <InjectedElement> elementsToIterate =
(this.checkedElements! = null? this.checkedElements : this.injectedElements);
IF) {(elementsToIterate.isEmpty (www.jinyazptdL.cn!)
Boolean logger.isDebugEnabled Debug = ();
for (InjectedElement Element: elementsToIterate) {
IF (Debug) {
logger.debug ( "Processing Injected of the bean Element ' "+ the beanName +"': "Element +);
}
// call AutowiredFieldElement method inject or injection AutowiredMethodElement object attribute value
element.inject (target, beanName, pvs) ;
}
}
}
AutowiredFieldElement#inject
@Override
protected void inject(Object bean, String beanName, 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<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 在容器中获取需要装配的Bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
...
}
if (value != null) {
// 通过反射设置属性值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
AutowiredMethodElement#inject
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
Class<?>[] paramTypes = method.getParameterTypes();
arguments = new Object[paramTypes.length];
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeans = new LinkedHashSet<String>(paramTypes.length);
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
// 在容器中获取需要装配的Bean
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
Arguments [I] = Arg;
}
the catch (BeansException EX) {
the throw new new UnsatisfiedDependencyException (null, the beanName, new new InjectionPoint (methodParam), EX);
}
}
...
}
IF (! = Null arguments) {
the try {
// element value set by calling method reflected
ReflectionUtils.makeAccessible (method);
Method.invoke (the bean, arguments);
}
...
}
}
from here we can see the source and AutowiredMethodElement AutowiredFieldElement complete automatic assembly are looking go container corresponding Bean, then the acquired reflected by the target object disposed Bean to Bean complete the automatic assembly.

Summary
we can see Spring Bean automated assembly process is:

The Class object, acquired by the reflection of all the Field and Method information
through reflection acquiring Field and Method of annotation information, and according to the annotation type, whether it is necessary to automatically assemble
elements will be automatically assembled, packaged AutowiredFieldElement and AutowiredMethodElement objects
calls AutowiredFieldElement and AutowiredMethodElement the inject method evoke a subsequent step
to find the source data to be injected by getBean calling the container () method Bean
Bean into the target Bean the source data reflecting the found
problems in the automatic assembly process also involves cycle dependent interest Spring can look at this article source (eight) circular dependencies

Guess you like

Origin www.cnblogs.com/dakunqq/p/11616879.html
Recommended