Home  >  Article  >  Java  >  Detailed explanation of the principle of Spring automatic assembly implemented by Java annotation mechanism

Detailed explanation of the principle of Spring automatic assembly implemented by Java annotation mechanism

黄舟
黄舟Original
2017-10-18 10:06:162251browse

This article mainly introduces the Spring automatic assembly implementation principle of the Java annotation mechanism in detail. It has a certain reference value. Interested friends can refer to

The main use of annotations in Java In SpringMVC (Spring Boot, etc.), annotations are actually equivalent to a markup language, which allows you to dynamically operate on members that have the markup at runtime. Note: The spring framework does not support automatic assembly by default. To use automatic assembly, you need to modify the autowire attribute of the 60e23eb984d18edbb092da6b8f295aba tag in the spring configuration file.

The automatic assembly attribute has 6 optional values, each representing different meanings:

byName ->When obtaining the target object from the Spring environment, the properties in the target object will Find the id attribute value of the 60e23eb984d18edbb092da6b8f295aba tag in the entire Spring environment based on the name. If there are the same, then obtain this object and implement the association. The entire Spring environment: means searching in all spring configuration files, then the ID cannot be repeated.

byType ->When obtaining the target object from the Spring environment, the attributes in the target object will search for the class attribute value of the 60e23eb984d18edbb092da6b8f295aba tag in the entire spring environment based on the type. If there are the same, then obtain this object and implement the association.

Disadvantages: If there are multiple bean objects of the same type, an error will occur; if the attribute is a single type of data, an error will occur if multiple associated objects are found; if the attribute is an array or collection ( Generic) type, then no exception will occur if multiple associated objects are found.

constructor ->Using the constructor method to complete object injection is actually an object search based on the parameter type of the constructor method, which is equivalent to using byType.

autodetect ->Automatic selection: If the object does not have a parameterless constructor, then the constructor's automatic assembly method is automatically selected for construction injection. If the object contains a parameterless constructor, the byType automatic assembly method is automatically selected for setter injection.                       

no ->Does not support the automatic assembly function

default ->Indicates that the value of the automatic assembly of the upper-level label is used by default. If there are multiple configuration files, the automatic assembly method of each configuration file is independent.

The use of annotations requires three conditions, including the annotation declaration, the element using the annotation, and the code that operates the annotation element. The first step is annotation declaration. Annotation is a type. The custom annotation writing code is as follows:


package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AttachAnnotation {
  String paramValue() default "河北省"; // 参数名为"paramValue" 默认值为"河北省"
}

Use custom annotation elements, the code is as follows:


package annotation;

/**
 * @author 路人宅
 */
public class AttachEmlement {

  // 普通
  public void AttachDefault(String name){
    System.out.println("归属:" + name);
  }
  
  // 使用注解并传入参数
  @AttachAnnotation(paramValue="河北省")
  public void AttachAnnotation(String name){
    System.out.println("归属:" + name);
  }
  
  // 使用注解并使用默认参数
  @AttachAnnotation
  public void AttachAnnotationDefault(String name){
    System.out.println("归属:" + name);
  }
}

The test operation executes the main function. The specific code is as follows:


package annotation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class AnnotionOperator {
 public static void main(String[] args) throws IllegalAccessException,
  IllegalArgumentException, InvocationTargetException,
  ClassNotFoundException {
 AttachEmlement element = new AttachEmlement(); // 初始化一个实例,用于方法调用
 Method[] methods = AttachEmlement.class.getDeclaredMethods(); // 获得所有方法

 for (Method method : methods) {
  AttachAnnotation annotationTmp = null;
  if ((annotationTmp = method.getAnnotation(AttachAnnotation.class)) != null)
  method.invoke(element, annotationTmp.paramValue());
  else
  method.invoke(element, "河南省");
 }
 }
}

Execution result:

Affiliation: Henan Province
Affiliation: Hebei Province
Affiliation: Hebei Province

Spring has two ways to operate in order to facilitate automatic assembly: inherit org.springframework.web. context.support.SpringBeanAutowiringSupport class or add @Component/@Controller and other annotations and declare the context:component-scan element configuration in the Spring configuration file.

1) Inheritance method realizes automatic wiring. Looking at the Spring3.1.1 source code, you will find the following code in the SpringBeanAutowiringSupport class:


/**
 * This constructor performs injection on this instance,
 * based on the current web application context.
 * Intended for use as a base class.
 * @see #processInjectionBasedOnCurrentContext
 */
public SpringBeanAutowiringSupport() {
 processInjectionBasedOnCurrentContext(this);
}

Analysis: Java will call the default parent class parameterless constructor when instantiating and constructing, and Spring uses this to execute the operation element code.

2) The annotation method is similar to the above theory. It is worth noting that the annotation automatic assembly does not need to complete the injection of setter*. Check the Spring3.1.1 source code annotation calling sequence to get:
org.springframework.web .context.support.SpringBeanAutowiringSupport#SpringBeanAutowiringSupport=>
org.springframework.web.context.support.SpringBeanAutowiringSupport#processInjectionBasedOnCurrentContext=>
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#processInjection=>
org.springframework.beans.factory.annotation.InjectionMetadata#Injection, view the source code of the inject method as follows:


##

/**
 * Either this or {@link #getResourceToInject} needs to be overridden.
 */
protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable {
 if (this.isField) {
 Field field = (Field) this.member;
 ReflectionUtils.makeAccessible(field);
 field.set(target, getResourceToInject(target, requestingBeanName));
 }
 else {
 if (checkPropertySkipping(pvs)) {
  return;
 }
 try {
  Method method = (Method) this.member;
  ReflectionUtils.makeAccessible(method);
  method.invoke(target, getResourceToInject(target, requestingBeanName));
 }
 catch (InvocationTargetException ex) {
  throw ex.getTargetException();
 }
 }
}

Analysis: Spring automatic assembly through the above source code This is achieved through the reflection mechanism.

The above is the detailed content of Detailed explanation of the principle of Spring automatic assembly implemented by Java annotation mechanism. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn