一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java注解機制之Spring自動裝配實現原理詳解

Java注解機制之Spring自動裝配實現原理詳解

2021-01-20 14:57yoodb Java教程

這篇文章主要為大家詳細介紹了Java注解機制之Spring自動裝配實現原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下

 Java中使用注解的情況主要在SpringMVC(Spring Boot等),注解實際上相當于一種標記語言,它允許你在運行時動態地對擁有該標記的成員進行操作。注意:spring框架默認不支持自動裝配的,要想使用自動裝配需要修改spring配置文件中<bean>標簽的autowire屬性。

自動裝配屬性有6個值可選,分別代表不同的含義:

byName ->從Spring環境中獲取目標對象時,目標對象中的屬性會根據名稱在整個Spring環境中查找<bean>標簽的id屬性值。如果有相同的,那么獲取這個對象,實現關聯。整個Spring環境:表示所有的spring配置文件中查找,那么id不能有重復的。 

byType ->從Spring環境中獲取目標對象時,目標對象中的屬性會根據類型在整個spring環境中查找<bean>標簽的class屬性值。如果有相同的,那么獲取這個對象,實現關聯。

缺點:如果存在多個相同類型的bean對象,會出錯;如果屬性為單一類型的數據,那么查找到多個關聯對象會發生錯誤;如果屬性為數組或集合(泛型)類型,那么查找到多個關聯對象不會發生異常。

constructor ->使用構造方法完成對象注入,其實也是根據構造方法的參數類型進行對象查找,相當于采用byType的方式。

autodetect ->自動選擇:如果對象沒有無參數的構造方法,那么自動選擇constructor的自動裝配方式進行構造注入。如果對象含有無參數的構造方法,那么自動選擇byType的自動裝配方式進行setter注入。                     

no ->不支持自動裝配功能

default ->表示默認采用上一級標簽的自動裝配的取值。如果存在多個配置文件的話,那么每一個配置文件的自動裝配方式都是獨立的。

注解使用需要三個條件包括注解聲明,使用注解的元素,操作使用注解元素的代碼。第一步注解聲明,注解是一種類型,自定義注解編寫代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
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" 默認值為"河北省"
}

使用自定義注解元素,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
  }
}

測試操作執行main函數,具體代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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, "河南省");
 }
 }
}

執行結果:

歸屬: 河南省
歸屬:河北省
歸屬:河北省

Spring為了方便自動裝配進行操作有兩種方式:繼承org.springframework.web.context.support.SpringBeanAutowiringSupport類或者添加@Component/@Controller等注解并在Spring配置文件里聲明context:component-scan元素配置。

1) 繼承方式實現自動裝配,查看Spring3.1.1源代碼會發現SpringBeanAutowiringSupport類中有如下代碼:

?
1
2
3
4
5
6
7
8
9
/**
 * 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);
}

分析:Java在實例化構造時會調用默認父類無參構造方法,而Spring就是通過這一點,讓操作元素代碼執行的。

2) 通過注解方式的也和上述理論相似,值得注意的是注解自動裝配無需完成注入setter*,查看Spring3.1.1源碼注解調用順序得出:
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,查看inject方法源代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 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();
 }
 }
}

分析:通過上述源碼Spring自動裝配是通過反射機制來實現的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.yoodb.com/yoodb/article/detail/1310

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人精品午夜视频' | 女黑人尺寸bbb | 国产乱子伦一区二区三区 | 美女精品永久福利在线 | 亚洲日本中文字幕天堂网 | 欧美交换乱理伦片120秒 | 韩国情事伦理片观看地址 | 美国video| 欧美大片一区二区 | 欧美国产日韩综合 | 国产成人看片免费视频观看 | 久久伊人电影 | 国产麻豆在线观看网站 | 海绵宝宝第二季全集免费观看 | 女子监狱第二季未删减在线看 | jk制服白丝超短裙流白浆 | 国产精品久久免费 | 男人天堂网www | 午夜福到在线4国产 | 日本高清动作片www欧美 | 性白俄罗斯高清xxxxx | 精品无码久久久久久久久 | 成人看的羞羞视频免费观看 | 国产精品日本亚洲777 | 亚洲精品视频网 | 亚洲娇小性hd | 成人天堂入口网站 | 亚洲国产精品成人午夜在线观看 | 处女摘花视频 | 天天亚洲综合 | 日韩成a人片在线观看日本 日韩不卡一区二区 | 亚洲热在线观看 | ass天天裸妇pics| 精品国产乱码久久久久久免费流畅 | 狠狠五月天中文字幕 | 视频一区久久 | 美日毛片 | heyzo在线观看 | 四虎2021地址入口 | 色狼屋| 玩两个少妇女邻居 |