日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅谈spring之IoC控制反转

發布時間:2023/12/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈spring之IoC控制反转 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以下學習資料來源于b站動力節點

spring: 出現是在2002左右,解決企業開發的難度。減輕對項目模塊之間的管理,類和類之間的管理, 幫助開發人員創建對象,管理對象之間的關系。spring核心技術 ioc , aop 。能實現模塊之間,類之間的解耦合。

類之間的解耦合傳送門

spring

準備工作

spring的第一個核心功能ioc。

IoC (Inversion of Control) : 控制反轉, 是一個理論,概念,思想。
描述的:把對象的創建,賦值,管理工作都交給代碼之外的容器實現, 也就是對象的創建是由其它外部資源完成。

控制: 創建對象,對象的屬性賦值,對象之間的關系管理。
反轉: 把原來的開發人員管理,創建對象的權限轉移給代碼之外的容器實現。 由容器代替開發人員管理對象。創建對象,給屬性賦值。

那么正轉是什么?

正轉:由開發人員在代碼中,使用new 構造方法創建對象, 開發人員主動管理對象。

public static void main(String args[]){Student student = new Student(); // 在代碼中, 創建對象。--正轉。 }

容器:是一個服務器軟件, 一個框架(spring)

為什么要使用 ioc? : 目的就是減少對代碼的改動, 也能實現不同的功能。 實現解耦合。

java中創建對象的方式有哪些?

  • 構造方法 , new Student()
  • 反射
  • 序列化
  • 克隆
  • ioc :容器創建對象
  • 動態代理
  • ioc的體現

    servlet:

  • 創建類繼承HttpServlet
  • 在web.xml注冊servlet。
  • <servlet-name> myservlet </servlet-name> <servelt-class>com.pingfan.controller.MyServlet1</servlet-class>
  • 沒有創建Servlet對象,為什么可以用?是被Tomcat容器創建的。(Tomcat也是個容器,里面存放的有Servlet對象,Listener,Filter對象)
  • IoC的技術實現

    DI是ioc的技術實現。

    DI(Dependency Injection):依賴注入,只需要在程序中提供要使用的對象名稱就可以,至于對象如何在容器中創建,賦值,查找,都由容器內部實現。

    傳統的new對象

    Student stu=new Student();

    使用spring創建對象

    Student stu=(Student)ac.getBean("student");//ac是spring容器,從容器中根據id拿到對象即可。

    總結:spring是使用di實現了ioc的功能,spring底層創建對象,使用的是反射機制。(sring是一個容器,管理對象,給屬性賦值,底層是反射創建對象。)

    IOC控制反轉

    接下來進入正題spring的核心功能之一IOC。以下項目的實現以及代碼的完成皆來自于文章開頭的傳送門建議結合b站視頻進行學習。

    創建一個簡單的spring項目

    實現步驟:

    1.創建maven項目 2.加入maven的依賴spring的依賴,版本5.2.5版本junit依賴 3.創建類(接口和他的實現類)和沒有使用框架一樣, 就是普通的類。 4.創建spring需要使用的配置文件聲明類的信息,這些類由spring創建和管理 5.測試spring創建的。

    新建一個空工程,之后創建一個moudle,新建一個maven項目,選擇quickstart。(建議初學者跟著視頻走。本文只提供大致思路以及筆記)

    初學者可能會有的疑問

  • 為什么要創建一個空工程?
  • 因為在空工程下可以有很多的模塊,便于管理。比如你學習的spring全部放在spring工程下。學習springmvc則放在springmvc工程下。

  • 使用單元測試有何好處?
  • 首先使用單元測試需要加入junit依賴,其中在test包下的類叫做測試類。我們在開發過程中需要不停的測試自己的項目,而在test包下測試清晰明了,結構也很清楚,便于后續開發。

    創建service包下接口SomeService。

    package com.pingfan.service; public interface SomeService {void doSome(); }

    然后在service包下創建實現該接口的類。創建imp包下的類SomeServiceImpl

    package com.pingfan.service.imp; import com.pingfan.service.SomeService; public class SomeServiceImpl implements SomeService {@Overridepublic void doSome() {System.out.println("執行了someServiceImpl的doSome()方法");} }

    在test下創建MyTest進行測試

    傳統的創建對象的方式

    @Test public void test01(){//傳統的方法SomeService service=new SomeServiceImpl();service.doSome(); }

    現在通過spring來創建對象。

  • 需要有spring的配置文件beans.xml
  • 讀取spring配置文件讓spring幫我們管理對象。
  • 首先在resource下創建spring的配置文件(xml下有一個Spring Config)(快捷鍵方式:點擊resource,alt+fn+f12(聯想電腦需要使用fn),搜索xml,下尋找spring config)

    對spring配置文件分析:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">\<!--告訴spring創建對象聲明bean,就是告訴spring要創建某個類的對象id:對象的自定義名稱,唯一值。spring通過這個名稱找到對象class:類的全限定名稱(不能是接口,因為spring是反射機制創建對象,必須使用類)spring就完成 SomeService someService=new SomeService()spring是把創建好的對象放入到map中,spring框架有一個map存放對象的。springMap.put(id的值,對象);例如:springMap.put("someService",new SomeServiceImpl());一個bean標簽聲明一個對象。--><bean id="someService" class="com.pingfan.service.imp.SomeServiceImpl" ></bean> </beans>

    進行測試:

    @Testpublic void test02(){//使用spring創建對象//1.指定spring配置文件的名稱String config="beans.xml";//2.創建表示spring容器的對象,ApplicationContext//ApplicationContext就是表示spring容器,通過容器獲取了對象//ClassPathXmlApplicationContext:表示從類路徑中加載spring的配置文件ApplicationContext ac=new ClassPathXmlApplicationContext(config);//從容器中獲取某個對象,你要調用對昂的方法//getBean("配置文件中的bean的id值")SomeService service= (SomeService) ac.getBean("someService");//使用spring創建好的對象service.doSome();}/*獲取spring容器中java對象的信息*/@Testpublic void test03(){String config="beans.xml";ApplicationContext ac=new ClassPathXmlApplicationContext(config);int nums=ac.getBeanDefinitionCount();System.out.println("容器中定義的對象數量:"+nums);//容器中定義對象的名稱String names[]=ac.getBeanDefinitionNames();for(String name:names){System.out.println("對象名稱:"+name);}}

    總結:至此,完成了通過spring來創建對象,進而我們通過id來從spring容器拿到對象。接下來對spring創建執行的過程進行分析:首先我們需要創建spring容器對象ApplicationContext ac=new ClassPathXmlApplicationContext(config);在ClassPathXmlApplicationContext類的構造方法中會讀取config這個配置文件,在該配置文件中,遇到bean標簽時,spring會完成對象的創建工作,(通過反射機制來調用class屬性中類的構造方法創建對象,對象的名字就是id的屬性名,并把創建的對象放到map之中,因此對象就創建好了,這也解釋了為什么從ac.getBean("id")就能拿到對象了。另外spring創建對象默認調用該對象的無參構造)到這,spring容器ac也創建好了,我們就可以通過這個容器拿到容器中的對象了。

    spring創建一個非自定義類的對象

    剛剛我們通過spring創建的是我們自己定義的類的對象,當然非自定義的對象也可以通過spring創建。

    在beans.xml中配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--spring能創建一個非自定義類的對象么,創建一個存在的某個類的對象--><bean id="mydate" class="java.util.Date"></bean> </beans>

    進行測試

    @Test public void test04(){String config="beans.xml";ApplicationContext ac=new ClassPathXmlApplicationContext(config);Date mydate =(Date) ac.getBean("mydate");System.out.println("Date:"+mydate); }

    屬性賦值

    傳統的的給屬性賦值

    學到這里,我們應該知道的是spring已經完成了對象的創建工作,那么,我們接下來關心的問題就是如何給對象的屬性賦值,在這個問題之前,我們可以通過spring這個容器拿到這個對象,然后利用該對象的get和set方法對該對象進行賦值和取值。(是不是又走老套路了?別急,讓你深入理解spring的創建對象,賦值的過程)

    實現步驟:在之前項目的基礎上,在com.pingfan包下新建model包(存放的是實體類),在model下新建Studnet實體類

    Student.java

    package com.pingfan.model;public class Student {private int id;private String name;private String address;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", address='" + address + '\'' +'}';} }

    接下來進行測試:

    在測試前記得在bean.xml中用bean標簽聲明該對象(目前為止學到的一種方法),由于本文篇幅過多,所以省略配置文件信息。相信可以舉一反三,不聲明該對象創建spring容器時,讀取配置文件就不會創建Student對象,同樣getBean("id")也拿不到該對象。

    <bean id="student" class="com.pingfan.model.Student"></bean> @Testpublic void test05(){String config="beans.xml";ApplicationContext ac=new ClassPathXmlApplicationContext(config);Student stu=(Student) ac.getBean("student");stu.setId(1);stu.setName("張三");stu.setAddress("河南省");System.out.println(stu);}

    結果:

    Student{id=1, name='張三', address='河南省'}

    總結:實踐檢驗真理,相信有人剛學spring當他從spring容器中拿到對象時,再學習給對象賦值時,首先想到的方法肯定是調用該對象的set方法。=~=!接下里步入正題,兩種方式為對象賦值分別是基于XML的DI(理解)和基于注解的DI(重點掌握),后期我們用到的都是基于注解的DI,在我一刷spring時xml方式快速略過,二刷時又重新復習了一遍。主要想深入理解其原理實現。

    學習下面之前

    DI的實現有兩種:

  • 在spring的配置文件中,使用標簽和屬性完成,叫做基于xml的di實現
  • 使用spring中的注解,完成屬性賦值,叫做基于注解的id實現。
  • 考慮到筆記放代碼過于冗余的原因,后面的篇幅只介紹具體功能的實現以及呈現部分的代碼,當然可以跟著文章開頭掛的傳送門進行學習

    基于XML的DI

    DI(Dependency Injection):依賴注入,表示創建對象,給屬性賦值。

    如何直接復制一份項目

    復制一份副本,修改自己的文件名。打開項目文件夾,把target目錄和xxx.iml文件刪除。打開pom.xml修改artifactId(最前邊的坐標)為自己的項目名字。然后導入module,選擇maven,修改下jdk點擊ok即可。其中target目錄是項目運行時才產生的目錄。

    注入分類

    (1)set注入(掌握)

    set注入(設置注入):spring調用類的set方法,在set方法可以實現屬性的賦值。80%都是使用的set注入。接下來具體看實現。

    簡單類型

    實體類:(因為只是賦值,所以僅僅用到了類的set方法)

    package com.pingfan.bao01; public class Student {String name;int age;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} }

    配置文件:bao01/applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 聲明Studnet對象注入:就是賦值的意思簡單類型:spring中規定java的基本數據類型hestring都是簡單類型di:給屬性賦值1.set注入(設置注入)<bean id="xx" class="yy"><property name="屬性名字" value="屬性的值">一個property只能給一個屬性賦值</property></bean>--><bean id="myStudnet" class="com.pingfan.bao01.Student"><property name="name" value="李四"></property><property name="age" value="20"></property></bean> </beans>

    測試:

    @Test public void test02(){String config="bao01/applicationContext.xml";ApplicationContext ac=new ClassPathXmlApplicationContext(config);Student myStudnet =(Student) ac.getBean("myStudnet");System.out.println("Studnet對象="+myStudnet); }

    結果:

    Studnet對象=Student{name='李四', age=20}

    總結:學到這里,我們學會了通過標簽<property name="屬性名字" value="屬性的值"></property>給對象的屬性賦值,實現過程就是通過對象的set方法實現的。初學者易犯的錯誤就是對整理目錄不夠清晰明了,導致運行報錯,在這里我們是在resource包下創建了bao01/applicationContext.xml而我們在test下寫的config當然也得包括包名,resource下的所有文件夾以及文件最后都會被放到targect/classes目錄下。所以讀取配置文件時一定要記得寫上包名。

    引用類型

    實體類:

    package com.pingfan.bao02; public class Student {String name;int age;//聲明一個引用類型School school;public void setSchool(School school) {this.school = school;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", school=" + school +'}';} } package com.pingfan.bao02; public class School {String name;String adress;public void setName(String name) {this.name = name;}public void setAdress(String adress) {this.adress = adress;}@Overridepublic String toString() {return "School{" +"name='" + name + '\'' +", adress='" + adress + '\'' +'}';} }

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 聲明Studnet對象注入:就是賦值的意思簡單類型:spring中規定java的基本數據類型hestring都是簡單類型di:給屬性賦值1.set注入(設置注入)<bean id="xx" class="yy"><property name="屬性名字" value="屬性的值">一個property只能給一個屬性賦值</property></bean>--><bean id="myStudent" class="com.pingfan.bao02.Student"><property name="name" value="李四"></property><property name="age" value="20"></property><property name="school" ref="mySchool"></property></bean><bean id="mySchool" class="com.pingfan.bao02.School"><property name="name" value="北京大學"></property><property name="adress" value="四合院"></property></bean> </beans>

    測試:

    @Test public void test01(){String config="bao02/applicationContext.xml";ApplicationContext ac=new ClassPathXmlApplicationContext(config);//School sc=(School)ac.getBean("mySchool");Student stu=(Student) ac.getBean("myStudent");//System.out.println("School="+sc);System.out.println("student="+stu); }

    結果:

    student=Student{name='李四', age=20, school=School{name='北京大學', adress='四合院'}}

    總結:在這里我們用到了ref指定的是類型對象(也就是id),同時我們也需要創建School對象,因此也把他放到了spring容器中,在這里可能有人疑惑當讀取spring配置文件時,如果Student在前,而ref指向的School對象在后面,肯定是先創建Student對象但是此時并沒有創建School對象,會不會找不到?。對此,spring非常的智能,他會二次掃描該配置文件,在第一次掃描時,他會把對象都創建出來,當在執行過程中找不到ref對應的對象,會進行二次掃描并找到進行賦值。因此第二次ref指向肯定會調用set方法給引用對象賦值了。

    (2)構造注入(理解)

    構造注入,spring調用類的有參數構造方法,創建對象。在構造方法中完成賦值。

    我們首先要知道spring默認調用的是無參構造,而這里我們通過有參構造對其賦值。

    在Studnet類中只需增加有參構造即可:

    public Student(String name, int age, School school) {this.name = name;this.age = age;this.school = school;System.out.println("有參構造方法"); }

    配置文件:

    name屬性

    <bean id="myStudent" class="com.pingfan.bao03.Student"><constructor-arg name="age" value="21"></constructor-arg><constructor-arg name="name" value="劉源"></constructor-arg><constructor-arg name="school" ref="mySchool"></constructor-arg> </bean> <bean id="mySchool" class="com.pingfan.bao03.School"><property name="name" value="北京大學"></property><property name="adress" value="四合院"></property> </bean>

    index屬性:這里的下標是和類的有參構造參數保持一致的。

    <bean id="myStudent2" class="com.pingfan.bao03.Student"><constructor-arg index="0" value="張三"></constructor-arg><constructor-arg index="1" value="20"></constructor-arg><constructor-arg index="2" ref="mySchool"></constructor-arg></bean>

    省略index屬性:默認跟類的有參構造保持一致。

    <bean id="myStudent2" class="com.pingfan.bao03.Student"><constructor-arg value="張三"></constructor-arg><constructor-arg value="20"></constructor-arg><constructor-arg ref="mySchool"></constructor-arg> </bean>

    引用類型屬性自動注入

    (1)byName方式自動注入

    java類中引用類型的屬性名和spring配置文件bean標簽id名稱一樣且數據類型一致,這樣的容器中的bean,spring能夠賦值給引用類型。

    配置文件:

    <bean id="myStudent" class="com.pingfan.bao04.Student" autowire="byName"><property name="name" value="李四"></property><property name="age" value="20"></property> </bean> <bean id="school" class="com.pingfan.bao04.School"><property name="name" value="北京大學"></property><property name="adress" value="四合院"></property> </bean>

    即該配置文件中的id屬性名school和Studnet類中引用類型名稱一樣,那么spring會為我們自動注入。

    (2)byType方式自動注入

    java類中引用類型的數據類型和spring容器中(配置文件)bean的class屬性是同源關系,這樣的bean能夠賦值給引用類型。

    同源:

  • java類中引用類型的數據類型和bean的class的值是一樣的。
  • java類中引用類型的數據類型和bean的class的值父子類關系的。
  • java類中引用類型的數據類型和bean的class得值接口和實現類關系的。
  • 第一種:

    配置文件:

    <bean id="myStudent" class="com.pingfan.bao05.Student" autowire="byType"><property name="name" value="李四"></property><property name="age" value="20"></property> </bean> <bean id="myschool" class="com.pingfan.bao05.School"><property name="name" value="清華大學"></property><property name="adress" value="四合院"></property> </bean>

    分析:當有byType時,他會在Studnet類中找到引用類型,然后根據這個引用類型在spring配置文件中找對應的class比較其類型一樣就會進行注入。當然也存在問題,比如有好幾種跟Studen類中的引用類型一樣就會報錯。

    例如:

    <bean id="myStudent" class="com.pingfan.bao05.Student" autowire="byType"><property name="name" value="李四"></property><property name="age" value="20"></property> </bean> <bean id="myschool" class="com.pingfan.bao05.School"><property name="name" value="清華大學"></property><property name="adress" value="四合院"></property> </bean> <bean id="school" class="com.pingfan.bao05.School"><property name="name" value="xx大學"></property><property name="adress" value="xxx"></property> </bean>

    其中有兩個School類型。就會報錯。所以在byType中,在xml配置文件中聲明bean只能有一個符合條件的,多余一個就是錯誤的。

    總結:至此使用配置文件給屬性賦值結束,接下來學習注解給屬性賦值,也是后續開發中常用的方式。

    基于注解的DI

    通過注解完成java對象創建,屬性賦值.使用注解必須使用spring-aop依賴,而我們的項目在加入spring-context時就已經間接加入了spring-aop依賴。

    使用注解的步驟:

  • 加入maven的依賴spring-context,在你加入spring-context的同時,使用注解必須使用spring-apo依賴
  • 在類中加入spring的注解(多個不同功能的注解)
  • 在spring的配置文件中,加入一個組件掃描器的標簽,說明注解在你的項目中的位置
  • 通過spring的注解完成java對象的創建,屬性。代替xml文件。

    學習的注解:
    1.@Component
    2.@Respotory
    3.@Service
    4.@Controller
    5.@Value
    6.@Autowired
    7.@Resource

    定義Bean的注解@Component

    在bao01中創建Student類

    package com.pingfan.bao1; import org.springframework.stereotype.Component; /*** Component創建對象的* 屬性:value 就是對象的名稱,value值唯一*/ @Component(value = "mystudent") public class Student {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;} }

    配置文件:applicationContext.xml

    <?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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--組件掃描器component-scan工作方式:spring會掃描遍歷base-package指定的包,把包中和子包中所有的類,找到類中的注解,按照注解的功能創建對象,或給對象賦值--><context:component-scan base-package="com.pingfan.bao1;com.pingfan.bao2"/> </beans>

    測試:

    @Test public void test01(){String config="applicationContext.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(config);//從容器中獲取對象Student stu= (Student) ctx.getBean("mystudent");System.out.println("student="+stu); }

    結果:

    student=Student{name='null', age=null}

    總結:分析用注解創建對象的過程,學到這里可以往前回顧一下xml方式創建對象的過程。=~=!

    xml創建對象過程:首先讀取spring配置文件,遇到bean標簽那么根據反射機制把對象創建出來放到map中,我們通過getBean(“id”)拿到對象。

    注解創建對象過程:首先也是讀取配置文件,不過這回讀取的是組件掃描器,那么根據base-packge找相應的包下類,找到注解@Component(value = “mystudent”)然后創建該類對象(value可省略)(默認調用類的無參構造)。創建完成即在spring容器中,我們就可以通過之前的方式拿到對象。

    @Component:創建對象,等同于的功能。

    屬性:value就是對象的名稱,也就是bean中的id

    ? value的值是唯一的,創建的對象在整個spring容器中就一個。

    位置:在類的上面。

    @Component(value = “mystudent”)等同于

    <bean id=myStudent class="com.pingfan.bao01.Studnet"></bean>

    簡單類型屬性注入@Value

    實體類:

    package com.pingfan.bao2; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /*** Component創建對象的* 屬性:value 就是對象的名稱,value值唯一*/ @Component("mystudent2") public class Student2 {@Value(value = "李好")private String name;@Value(value = "20")private Integer age;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} }

    總結:其中value可省略,并且該方式也不需要set方法(當然如果有set方法@Value也可以放在set方法上同樣可以實現屬性賦值),簡單明了。

    byType自動注入@Autowired

    學習前建議回顧xml中的byType

    @Autowired:實現引用類型的賦值。

    spring中通過注解給引用類型賦值,使用的是自動注入原理。默認使用的是byType自動注入

    位置:

    1.在屬性定義的上面,無需set方法。推薦使用

    2.在set方法的上面。

    實體類:

    Student

    package com.pingfan.bao03; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Student {@Value(value = "李好")private String name;@Value(value = "20")private Integer age;@Autowiredprivate School school;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", school=" + school +'}';} }

    School

    package com.pingfan.bao03; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class School {@Value("家里蹲")String name;@Value("中國")String adress;@Overridepublic String toString() {return "School{" +"name='" + name + '\'' +", adress='" + adress + '\'' +'}';} }

    配置文件:applicationContext.xml

    <?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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--組件掃描器component-scan工作方式:spring會掃描遍歷base-package指定的包,把包中和子包中所有的類,找到類中的注解,按照注解的功能創建對象,或給對象賦值--><context:component-scan base-package="com.pingfan.bao03"/> </beans>

    測試:

    @Test public void test01(){String config="applicationContext.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(config);//從容器中獲取對象Student stu= (Student) ctx.getBean("student");System.out.println("student="+stu); }

    總結:這里將之前所學的注解創建對象,@Value注入都融入到這里了,可以看到配置文件中就有一個組件掃描器,然后根據base-package找相應的包下的類(即Student和School),看到該類有注解@Component就會創建該類對象,以及@Value也會注入,找到School,看到該屬性上面有@Autowired,默認byType注入,那么就會找符合xml中介紹到的三種方式(這里符合第一種)進行注入。至此完成。

    byName自動注入@Autowired

    學習前建議回顧xml中的byName

    如果使用byName方式:

    1.在屬性上加@Autowired

    2.在屬性上加@Qualifier(value=“bean的id”):

    實體類:

    Student

    package com.pingfan.bao04; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Student {@Value(value = "李好")private String name;@Value(value = "20")private Integer age;@Autowired@Qualifier("school")private School school;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", school=" + school +'}';} }

    School

    package com.pingfan.bao04;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class School {@Value("家里蹲")String name;@Value("中國")String adress;@Overridepublic String toString() {return "School{" +"name='" + name + '\'' +", adress='" + adress + '\'' +'}';} }

    總結:相比byType,byName多加了一個注解(指定引用類型的bean中id),可以看到很多都內容都簡化了,@Component不在添加value那么默認就是類小寫名稱,以及@Value,在學習中可以檢驗自己是否真的掌握了這些東西。

    JDK注解@Resource自動注入

    Spring提供了對jdk@Resource注解的支持。@Resource注解既可以按名稱匹配Bean,也可以按類型匹配Bean。默認按名稱注入。使用該注解,要求jdk必須是6及以上版本。@Resource可在屬性或set方法上。

    (1)byType注入引用類型屬性

    @Resource注解若不帶任何參數,采用默認按名稱的方式注入,按名稱不能注入bean,則會按照類型進行Bean的匹配注入。

    (2)byName注入引用類型屬性

    總結:可以看到默認是按名稱,找不到則會按類型注入。

    注解與XML的對比

    XML

  • 優點:代碼和值是分開的,賦值都是在resource下的配置文件進行的,在這里修改完全不影響源代碼,這種方式對需要經常被改的值是非常有效的。
  • 缺點:代碼量多、長。有點繁雜,開發效率較低
  • 注解

  • 優點:方便快捷,容易記憶,效率高
  • 劣勢:注解嵌在源代碼里,結構復雜
  • 總結:經常改變的值使用配置文件,不經常改變的值使用注解。

    總結

    以上是生活随笔為你收集整理的浅谈spring之IoC控制反转的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。