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.
  
  FIG AutowiredAnnotationBeanPostProcessor class
  
  PriorityOrdered: Verify that the postprocessor AutowiredAnnotationBeanPostProcessor priority
  
  BeanFactoryAware: AutowiredAnnotationBeanPostProcessor that can be acquired directly by the BeanFactory Bean container
  
  BeanPostProcessor: postprocessor performed before and after the initialization Bean
  
  InstantiationAwareBeanPostProcessor: Bean disposed before and after the instantiation and Bean postprocessor performed when the property value
  
  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.
  
  Introduction postprocessor
  
  BeanPostProcessor
  
  There are two methods BeanPostProcessor, 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;
  
  (! Boolean.FALSE.equals (mbd.beforeInstantiationResolved)) IF {
  
  // the Make the Sure bean class IS AT Actually resolved the this Point.
  
  IF (mbd.isSynthetic () && hasInstantiationAwareBeanPostProcessors ()!) {
  
  Class determineTargetType the targetType = (the beanName, MBD) <?>;
  
  IF (! the targetType = null) {
  
  the bean = applyBeanPostProcessorsBeforeInstantiation (the targetType, the beanName);
  
  ! IF (the bean = null ) {
  
  // If this method returns a non-null object, the Bean is created during a short circuit.
  
  // further processing only application from the configured BeanPostProcessors of postProcessAfterInitialization callback
  
  bean = applyBeanPostProcessorsAfterInitialization (bean, beanName);
  
  protected Object applyBeanPostProcessorsBeforeInstantiation (Class beanClass, String beanName <?>) {
  
  For (the BeanPostProcessor BP: getBeanPostProcessors ()) {
  
  IF ( bp instanceof InstantiationAwareBeanPostProcessor) {
  
  IBP = InstantiationAwareBeanPostProcessor (InstantiationAwareBeanPostProcessor) BP;
  
  // instantiate Bean performed before audiences post-processing method
  
  Object ibp.postProcessBeforeInstantiation Result = (beanClass, the beanName);
  
  IF (! Result = null) {
  
  return Result;
  
  follow-up, we can source see, if this method returns a non-null object, the Bean is created during 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 of automatic assembly required
  
  AutowiredAnnotationBeanPostProcessor post processor is mainly responsible for the automatic 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 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition this method, the following call link:
  
  doWith: 445, AutowiredAnnotationBeanPostProcessor $ 2 (the org.springframework.beans.factory.annotation)
  
  doWithLocalFields: 657, ReflectionUtils (org.springframework.util)
  
  buildAutowiringMetadata: 433, the AutowiredAnnotationBeanPostProcessor (the org.springframework.beans.factory.annotation)
  
  findAutowiringMetadata: 412, the AutowiredAnnotationBeanPostProcessor (the 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)
  
  the getBean: 197, AbstractBeanFactory (org.springframework.beans.factory.support)
  
  's internal preInstantiateSingletons: 761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
  
  finishBeanFactoryInitialization: 867, the AbstractApplicationContext (org.springframework.context.support)
  
  Refresh: 543, the AbstractApplicationContext (xingtuylgw.com org.springframework.context.support)
  
  <the init>: 84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
  
  we can see from the link, the need to find elements are implemented in the automated assembly process findAutowiringMetadata , 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:
  
  InjectionMetadata buildAutowiringMetadata Private (<?> final Class clazz) {
  
  LinkedList <InjectionMetadata.InjectedElement> Elements = new 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.haojiangyule.com ();
  
  // find all Class Field corresponding to the object by reflecting
  
  ReflectionUtils.doWithLocalFields (targetClass, new new ReflectionUtils.FieldCallback () {
  
  @Override
  
  void doWith public (field, field) throws an IllegalArgumentException, IllegalAccessException {
  
  // find all annotation information by reflection on the field, and determines whether there @Autowired and @Value annotations, if it is sealed into the field objects AutowiredFieldElement
  
  Ann findAutowiredAnnotation = AnnotationAttributes (Field);
  
  IF (! = Null Ann) www.yuntianyul.com {
  
  IF (Modifier.isStatic (field.getModifiers ())) {
  
  IF (logger.isWarnEnabled (www.hongyaoyul.cn)) {
  
  Logger .warn ( "Annotation Autowired is Not Supported IS ON static fields:" field +);
 
  
  Boolean = determineRequiredStatus required (Ann) ;,
  
  // AutowiredFieldElement sealed into the field object into the cache and
  
  currElements.add (new AutowiredFieldElement (field , required));
  
  }
  
  }
  
  });
  
  // Method to identify all the corresponding Class objects by reflection
  
  ReflectionUtils.doWithLocalMethods (targetClass, new new ReflectionUtils.MethodCallback () {
  
  @Override
  
  public void doWith (Method Method) throws an IllegalArgumentException, IllegalAccessException {
  
  BridgedMethod = BridgeMethodResolver.findBridgedMethod Method, (Method);
  
  (! BridgeMethodResolver.isVisibilityBridgeMethodPair (Method, bridgedMethod)) IF {
  
  return;
  
  }
  
  // Find all annotation information by reflection on the field, and determines whether there is @Autowired and @Value annotations, If there is 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 ( www.jintianxuesha.com))) {
  
  IF (logger.isWarnEnabled ()) {
  
  logger.warn ( "Annotation Autowired is Not Supported IS ON static Methods:" + Method);
  
  }
  
  return;
  
  }
  
  IF (Method.getParameterTypes (www.baichuangyule .cn) .length == 0) {
  
  IF (logger.isWarnEnabled ()) {
  
  logger.warn ( "Annotation Should Autowired is ON Methods Used with only BE Parameters:" +
  
  Method);
  
  }
  
  }
  
  Boolean = determineRequiredStatus required (Ann);
  
  the PropertyDescriptor PD = BeanUtils.findPropertyForMethod (bridgedMethod, clazz );
  
  // sealed into the field AutowiredMethodElement objects
  
  currElements.add (new new AutowiredMethodElement (Method, required, PD));
  
  }
  
  }
  
  });
  
  elements.addAll (www.yuchengyuledl.com 0, currElements);
  
  targetClass = targetClass.getSuperclass ();
  
  }
  
  // loop process to be automatically assembled parent element
  
  the while (targetClass = null && targetClass = Object.class!!);
  
  // will automatically assemble elements that need to be packaged InjectionMetadata object definition and merged into Bean
  
  new new InjectionMetadata return (clazz, Elements);
  
  }
  
  Find require automatic assembly process:
  
  The Class object, by reflection and get all the Field `` `Method```` target
  
  acquisition and annotations on the Field Method by reflection, and determines whether there @Autowired and @Value annotation
  
  to the annotated @Autowired @Value and Method Field and encapsulated into objects AutowiredMethodElement AutowiredFieldElement 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:
  
  public void Inject (Object target, String the beanName, the PropertyValues PVS) throws the Throwable {
  
  // Get automatic assembly requires metadata information (cache where it is taken)
  
  Collection <InjectedElement> = elementsToIterate
  
  (this.checkedElements != null ? this.checkedElements : this.injectedElements);
  
  if (!elementsToIterate.isEmpty()) {
  
  boolean debug = logger.isDebugEnabled();
  
  for (InjectedElement element : elementsToIterate) {
  
  if (debug) {
  
  logger.debug("Processing injected element of bean '" + beanName + "': " + element);
  
  }
  
  // 调用AutowiredFieldElement或AutowiredMethodElement对象的inject方法注入属性值
  
  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;
  
  }
  
  catch (BeansException ex) {
  
  new new UnsatisfiedDependencyException the throw (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 Bean go find the corresponding container, and then reflected by the acquired setting to a target Bean object, to complete the automatic assembly of the Bean.
  
  Summary
  
  we can see Spring Bean is an automatic assembly process:
  
  The Class object, and Method Field obtain all information by reflection
  
  on the reflection and Method Field of acquiring annotation information, and according to the type of annotation, it is determined whether the automatic assembly
  
  would be automatically assembled elements, encapsulated into objects AutowiredFieldElement and AutowiredMethodElement
  
  Call AutowiredFieldElement and inject method AutowiredMethodElement to evoke a subsequent step
  
  to find the source data to be injected by getBean calling the container () method Bean
  
  source data reflecting the found Bean into the target Bean the
  
  problems in the automatic assembly process also involves cycle dependent , are interested you can look at this article Spring source (eight) circular dependencies

Guess you like

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