Spring詳細講解@Autowired注解
java注解
在解釋spring的注解之前,先了解一下什么是java的注解?:Java 注解(Annotation)又稱 Java 標注,是 JDK5.0 引入的一種注釋機制。
Java中類、變量、參數、 包等都可以添加注解,java的注解可以通過反射來獲取到標注的內容,在編譯器生成字節(jié)碼文件時,標注信息也添加進去。當運行時,JVM可以根據標注信息獲取相應的信息。
先給大家介紹一下java中常見的7種注解,這種注解也是spring中的注解的基礎!前三個注解是用于代碼上的注解,剩下的四個是用于修飾注解!
- @Override - 檢查該方法是否是重寫方法。如果發(fā)現其父類,或者是引用的接口中并沒有該方法時,會報編譯錯誤。
- @Deprecated - 標記過時方法。如果使用該方法,會報編譯警告。
- @SuppressWarnings - 指示編譯器去忽略注解中聲明的警告。
- @Retention - 標識這個注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運行時可以通過反射訪問。
- @Documented - 標記這些注解是否包含在用戶文檔javadoc中。
- @Target - 標記這個注解應該是哪種 Java 成員。
- @Inherited - 標記這個注解是繼承于哪個注解類(默認 注解并沒有繼承于任何子類)
spring注解
然后我們來說一下spring中注解的作用。
spring的重要特征就是控制反轉和依賴注入。在spring中,將部分需要創(chuàng)建和生成的類的控制權限交給了spring容器進行管理,這就是控制反轉。依賴注入就是將屬性和類信息注入給相應的類。而這和我們要使用的注解有什么關系呢?
(1)配置文件形式
我們知道在出現注解之前,spring實現bean的管理是通過配置文件來實現的,所以我們先設計一個簡答的bean來實現一下,如下:結構圖在下面,為了方便我把代碼放到了一起,實現請對比結構圖!
package com.example.school; import com.example.studuent.*; public class chuzhong { private lisi Lisi; private zhangsan ZhangSan; public void setLisi(com.example.studuent.lisi Lisi) { this.Lisi = Lisi; } public void setZhangsan(com.example.studuent.zhangsan ZhangSan) { this.ZhangSan = ZhangSan; } public com.example.studuent.lisi getLisi() { return Lisi; } public com.example.studuent.zhangsan getZhangsan() { return ZhangSan; } public String toString() { return Lisi.name; } } package com.example.studuent; public class lisi { public String name = "李四"; public void setName(String name) { this.name = name; } public String getName() { return name; } public String studentname(){ return name; } } package com.example.studuent; public class zhangsan { public String name = "張三"; public void setName(String name) { this.name = name; } public String getName() { return name; } public String studentname(){ return "這個學生是:" + name; } } import com.example.school.*; import com.example.studuent.lisi; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class annotationExample { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); chuzhong cz = (chuzhong) context.getBean("chuzhong"); String name = cz.getLisi().studentname(); System.out.println(name); } }
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <bean id="chuzhong" class="com.example.school.chuzhong" > <property name="lisi" ref="lisi" /> <property name="zhangsan" ref="zhangsan" /> </bean> <bean id="lisi" class="com.example.studuent.lisi" /> <bean id="zhangsan" class="com.example.studuent.zhangsan" /> </beans>
運行結果:
可以看到,加載了相應的配置文件,然后spring容器依次創(chuàng)建了相應的實例對象。并成功輸出的lisi實例對象的姓名。
這就是未使用注解時候,bean的使用方法。
(2)注解形式
加入了注解之后,我們會省下配置很多不必要信息的時間。最常用的自動裝配的注解@Autowired,用于放置在類上用來修飾。
可以了解一下@Autowired的源碼中的注解信息,咱們簡單看一個重要的信息
這個說,構造函數、字段、setter方法或config方法標記為由Spring的依賴項注入工具自動連接。
而@Autowired這個注解對應的,就是我們在chuzhong類中,寫的set和get方法,以及配置文件中的property標簽的內容,它可以幫我們自動關聯(lián)bean對象,實現自動裝配功能。
所以我們使用@Autowired注解之后的類文件和配置文件就變成了如下圖,關聯(lián)的zhangsan和lisi類對象的set和get方法省略,并且配置文件中property中內容省略,但是需要加上component-scan組件掃描配置,因為當出現@Autowired注解之后,會從base-package下查找相應的關聯(lián)bean對象:
@Autowired的解析
我們來分析一下@Autowired中都是什么東西:
1,首先注解是使用@interface修飾的,意味著它實現了 java.lang.annotation.Annotation 接口,使用@interface修飾才可以生成注解的形式
2,綠色字體的意思,注解依賴是否是必須的,也就是你使用了@Autowired這個注解,那么可以手動配置required,是否使用,默認是寫了該注解就是使用
3,我們在文章第一段說明了,有四個注解是用來修飾注解的。我用一段來解釋一下其中字段的意思。
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) 表示這個注解是用來修改哪種成員的,如果沒有寫這個@Target則表示,它可以用在任何地方。然后我們了解一下ElementType這個枚舉類中中各個字段的意思。從下面我們可以看出,它可以修飾構造器、方法、參數、成員變量以及注解。所以多個ElementType對應一個注解。
TYPE: 能修飾類、接口或枚舉類型
FIELD: 能修飾成員變量
METHOD: 能修飾方法
PARAMETER: 能修飾參數
CONSTRUCTOR: 能修飾構造器
LOCAL_VARIABLE: 能修飾局部變量
ANNOTATION_TYPE: 能修飾注解
PACKAGE: 能修飾包
TYPE_PARAMETER: 能修飾類型參數
TYPE_USE: 所有類型都可以修飾(不包括類)
@Retention(RetentionPolicy.RUNTIME)用于指定該注解的生命周期,存活到什么時候,RUNTIME表明存活到運行時,可以反射獲取相應的信息。
SOURCE:該注解存在于源碼中,當編譯成字節(jié)碼時,就消失了。
CLASS: 該注解在java文件生成字節(jié)碼文件后,存在于字節(jié)中,但是在jvm運行中就沒了。@Retention的默認值,即當沒有顯式指定@Retention的時候,就會是這種類型。
RUNTIME: 該標注信息存在字節(jié)碼中,jvm運行該字節(jié)碼時,可以通過標注獲取相應的信息
@Documented文中第一段有說明。
@Autowired的生效流程
而@Autowired是如何生效的呢?我引用一下別人的文章:SpringBoot中@Autowired是如何生效的,希望大家也可以看一看,我摘重點說一下。下圖就是spring啟動之后的流程。
首先是AutowiredPorcessor的BeanDefinition的注冊
1, 創(chuàng)建ApplicationContext
2, 創(chuàng)建AnnotatedBeanDefinitionReader
3, 注冊BeanDefinition registerAnnotationConfigProcessors
然后是AutowiredProcessor注冊為bean
1,registerBeanPostProcessors
最后是注入
1,獲取bean getBean()
2,創(chuàng)建bean doCreateBean()
?3,生成bean populateBean()
4,應用AutowiredProcessor ibp.postProcessProperties()
5,找到可注入的字段 buildAutowiringMetadata
6,注入 metadata.inject
spring的其余注解也可以參考這種形式,逐一進行分析,個人的注解放到(二)中實現。
到此這篇關于spring詳細講解@Autowired注解的解析的文章就介紹到這了,更多相關spring @Autowired內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
mybatis interceptor 處理查詢參數及查詢結果的實例代碼
這篇文章主要介紹了mybatis interceptor 處理查詢參數及查詢結果,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-01-01