欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Bean常用的的裝配方式詳解

 更新時間:2019年07月03日 08:26:28   作者:chenhongyong  
這篇文章主要介紹了Spring Bean常用的的裝配方式詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

Bean常用的裝配方式有3種:

  • 基于xml的裝配
  • 基于Annotation(注解)的裝配
  • 基于Java配置類的裝配

基于xml的裝配

在xml文件中配置Bean。

如果依賴很多,xml配置文件會很臃腫,后期維護、升級不方便。自動裝配可解決這一問題。

基于xml的自動裝配

在<bean>中使用autowired屬性完成依賴的自動裝配,不再使用<property>手動注入setter方法中的依賴,簡化了配置,減少了xml中的代碼量。

autowire屬性的屬性值:

  • no 不使用自動裝配。缺省autowire屬性時默認(rèn)值就是no。
  • byName 根據(jù)setter方法的名稱來自動裝配
  • byType 根據(jù)所依來的類型(Bean)來自動裝配
  • constructor 根據(jù)構(gòu)造函數(shù)的形參表的數(shù)據(jù)類型進行byType方式的自動裝配
  • default 全局自動裝配

1、byName

示例:

class Student{
 private String name;
 public Student(String name){
  this.name=name;
 }
 public String getName(){
  return name;
 }
}
class Teacher{
 private Student student;
 public void setStudent(Student student) {
  this.student = student;
 }
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

Teacher依賴于Student,依賴的對象要寫成成員變量的形式。如果要使用自動裝配,依賴對象的注入只能使用setter方式。

byName,name指的是setXxx()注入依賴的那個xxx,比如setStudent(Student student),name指的是student,將set后面的部分提出來,變成Camel寫法。name不是指形參名的student。

xml中的配置:

  <bean id="student" class="my_package.Student">
<constructor-arg value="張三" />
</bean>
<bean id="teacher" class="my_package.Teacher" autowire="byName" />

第一個Bean是基于xml的普通裝配,第二個Bean的配置是byName形式的自動裝配。

byName自動裝配的執(zhí)行過程:在這個Bean的定義中,找到setter方法,這里是setStudent(),其name是student(set后面部分提出來,變成Camel寫法),根據(jù)這個name(student)找打到id/name是student的Bean實例,將這個實例自動注入。

所以對<bean>的id/name、setter方法的命名有嚴(yán)格要求。

原本是要用<property name ref="" />子元素注入依賴的,如果依賴較多,會寫一大堆<property>子元素。自動裝配,不管這個一Bean有多少個依賴,一句代碼搞定,減少了代碼量,由Spring容器自動注入依賴。但Spring容器要做更多的工作,裝配速度會變慢。

說明:自動裝配只能完成setter形式的依賴注入,不能完成構(gòu)造器方式的依賴注入,且只能注入其它Bean,不能注入String、數(shù)組、集合等Java自帶的類型。

測試代碼:

public class Test {
 public static void main(String[] args) {
  ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
  Teacher teacher=applicationContext.getBean("teacher",Teacher.class);
  teacher.say();
 }
}

運行,控制臺打印出"張三,叫家長來一下。"。

2、byType

根據(jù)要注入的Bean的類型來自動裝配。

在上面的例子中,setStudent(Student student),要注入的依賴是Student類型的實例。

byType自動裝配的執(zhí)行過程:在這個Bean的定義中,找到setter方法,找到setter方法要注入的Bean的類型(Student),在Spring容器中找到Student類型的實例,注入。

如果Spring容器中該依賴有多個配置,比如:

<bean id="student" class="my_package.Student">
  <constructor-arg value="張三" />
 </bean>
 <bean id="student1" class="my_package.Student">
  <constructor-arg value="李四" />
 </bean>

它們都是Student這個Bean的配置,Spring容器不知道要注入的依賴是哪一個,會報錯,所以依賴的bean只能有一個配置。

這種是可以的:

  <bean id="student" class="my_package.Student" scope="prototype">
<constructor-arg value="張三" />
</bean>

雖然Spring容器中可能有這個Bean的多個實例,但這些實例是一樣的。

示例:

將byName示例中的xml中的配置修改如下即可

  <bean id="student" class="my_package.Student">
<constructor-arg value="張三" />
</bean>
<bean id="teacher" class="my_package.Teacher" autowire="byType" />

3、constructor

class Student{
 public String getName(){
  return "張三";
 }
}
class Teacher{
 private Student student;
 public Teacher(Student student){
  this.student=student;
 } 
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

需要用構(gòu)造器注入依賴,Spring容器會自動根據(jù)構(gòu)造器中參數(shù)類型,用byType方式注入對應(yīng)類型的依賴。

只能有一個構(gòu)造器,否則Spring容器不知道使用哪個構(gòu)造器。

xml中的配置:

<bean id="student" class="my_package.Student" />
<bean id="teacher" class="my_package.Teacher" autowire="constructor" />

4、default

<?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"
  default-autowire="byName">
 <bean id="student" class="my_package.Student">
  <constructor-arg value="張三" />
 </bean>
 <bean id="teacher" class="my_package.Teacher" autowire="default" />

在<beans>中設(shè)置默認(rèn)的自動裝配方式,在需要使用自動裝配的<bean>指定autowire="default",這樣該<bean>使用的自動裝配方式就是<beans>中設(shè)置的默認(rèn)方式。

統(tǒng)一了應(yīng)用的自動裝配方式。

基于注解的裝配

基于xml裝配的方式,如果<bean>很多,xml文件依然很臃腫?;谧⒔獾难b配解決了這一問題。

基于注解的裝配是最常用的。

Spring常用的注解:

  • @Autowired 按類型自動裝配(byType)。
  • @Qualifier 按名稱自動裝配,不能單用,需要和@Autowired配合使用(byName)。
  • @Resource 是byName、byType方式的結(jié)合。

記法:Autowired——Type,Qualifier——Name,ATQN。

示例 @Autowired

class Student{
 private String name;
 public Student(String name){
  this.name=name;
 }
 public String getName(){
  return name;
 }
}
class Teacher{
 @Autowired
 private Student student;
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

不必寫setter方法,也不必寫構(gòu)造器。在依賴的對象上添加@Autowired注解(當(dāng)然也可以在setter方法上寫),即按照類型自動裝配依賴。

上面在Student類型的依賴上添加了@Autowired注解,會自動在Spring容器中,找到Student類型的Bean,注入。相當(dāng)于byType。

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  <context:annotation-config />
 <bean id="student" class="my_package.Student">
  <constructor-arg value="張三" />
 </bean>
 <bean id="teacher" class="my_package.Teacher"/>
</beans>

基于注解的裝配都需要用<context:annotation-config />開啟注解裝配,這句代碼是告訴Spring容器,下面的這些bean使用的是注解裝配。

<bean>中不使用autowire屬性。

測試:

public class Test {
 public static void main(String[] args) {
  ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
  Teacher teacher=applicationContext.getBean("teacher",Teacher.class);
  teacher.say();
 }
}

可以看到控制臺打印出"張三,叫家長來一下。"。

示例 @Qualifier

修改Teacher類代碼如下,其余不變。

class Teacher{
 @Autowired
 @Qualifier(value="student")
 private Student student;
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

在依賴的Bean實例上添加@Qualifier,@Qualifier不能單獨用,還需要添加@Autowired。

@Qualifier是byName方式的自動裝配,需要用value指定依賴Bean的id/name,Spring容器根據(jù)這個value找到id/name為vBean,注入。

可簡寫為@Qualifier("student")。

示例 @Resource

class Teacher{
 @Resource(name = "student")
 private Student student;
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

先根據(jù)name找到Spring容器中name/id為student的Bean,注入。即優(yōu)先以getName方式。

如果找不到name/id為指定值的Bean,或缺省name直接寫@Resource,則以默認(rèn)的getName方式:寫在字段上默認(rèn)name為成員變量名(student),寫在setter方法上默認(rèn)為set后面部分得Camel寫法,比如setStudent()默認(rèn)name為student。

如果還是找不到依賴的Bean,則以byType方式注入。

說明

  • 以上注解寫在字段上、setter方法上均可,都是注入一個依賴。
  • Spring提供了@Resource注解,但此注解需要第三方包javax.annotation-api.jar的支持。如果用Maven,會自動添加Spring依賴的第三方包,比如commons-logging.jar、javax.annotation.jar,如果是自己添加Spring的jar庫,則還需要手動添加Spring依賴的第三方j(luò)ar包。
  • 需要在xml中用<context:annotation-config />開啟注解。

Spring常用的其它注解

  • @Service 將業(yè)務(wù)層(Service層)的類標(biāo)識為Spring容器中的Bean
  • @Controller 將控制層的類標(biāo)識為Spring容器中的Bean
  • @Repository 將數(shù)據(jù)訪問層(Dao層)的類標(biāo)識為Spring容器中的Bean
  • @Component 將一個類標(biāo)識為Spring容器中的Bean,相當(dāng)于具有以上3個注解的功能。但一般都使用專門的,就是說通常使用上面3個注解,很少使用@Component。

前3個是專用的,第四個是通用的。這些注解都只能在類(Bean)上使用。

示例

@Service
class Student{
 public String getName(){
  return "張三";
 }
}
@Service
class Teacher{
 @Resource(name = "student")
 private Student student;
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}

xml中的配置:

<context:component-scan base-package="my_package" />
<bean id="student" class="my_package.Student" /> 

需要使用 <context:component-scan base-package="" />指定要掃描的包,這樣會Spring容器會自動掃描指定的包,如果包中有上面4個注解,就將之裝配為Bean。

<context:component-scan base-package="" />會自動開啟注解,所以不必再寫<context:annotataion-config />。

其實上面4個注解的作用相當(dāng)于<bean class="" />。

標(biāo)注了這4個注解的類,Spring會自動在xml中把這個類配置為Bean,就是說在xml中不必寫<bean class="" />。

但只能是<bean class="" />這樣基礎(chǔ)的配置,如果要<constructor-arg>、<property>傳遞Java自帶類型的參數(shù),或其他Bean必須使用這個Bean的id/name(這個Bean要配置id/name),就不能省略該Bean的配置。

上面的例子中,Teacher類缺省了<bean class="my_package.Teacher" />。

@Resource(name = "student")
private Student student;

Teacher類要用到Student類的id/name,所以Student類寫了配置。

其實不寫Student類的配置,則會使用byType方式向Teacher注入依賴,也可以。

<context:component-scan base-package="my_package" />這句代碼不能缺省。

自動裝配簡化了配置,減少了代碼量,但需要Spring容器做更多的工作,所以創(chuàng)建Bean的速度要慢一些。

基于Java配置類的裝配

不使用xml文件配置Bean,而是單獨寫一個類來配置Bean。

class Student{
 private String name;
 public Student(String name){
  this.name=name;
 }
  public String getName(){
  return name;
 }
}
class Teacher{
 private Student student;
 public Teacher(Student student){
  this.student=student;
 }
  public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}
@Configuration //表示這個類是用來配置Bean的
class Config{
 @Value("張三") String name; //創(chuàng)建一個成員變量,相當(dāng)于String name="張三";
 @Bean(name = "student") //配置一個Bean,相當(dāng)于xml中的一個<bean>
 public Student student(){
  Student student=new Student(name); //創(chuàng)建并返回Bean的實例。
  return student;
 }
 @Bean(name = "teacher")
 public Teacher teacher(){
  return new Teacher(student()); //創(chuàng)建并返回Bean的實例,因為寫了構(gòu)造器,所以可以直接構(gòu)造器注入依賴。可直接調(diào)用本類中的其它方法創(chuàng)建依賴的實例,注入。
 }  
}
public class Test {
 public static void main(String[] args) {
  ApplicationContext applicationContext=new AnnotationConfigApplicationContext(Config.class); //注意,和xml配置不同。參數(shù)是配置類。
  Teacher teacher=applicationContext.getBean("teacher",Teacher.class);
  teacher.say();
 }
}

上面的例子是通過構(gòu)造器初始化Bean,也可以寫setter方法,通過setter方法初始化Bean:

class Student{
 private String name;
 public void setName(String name){
  this.name=name;
 }
 public String getName(){
  return name;
 }
}
class Teacher{
 private Student student;
 public void setStudent(Student student){
  this.student=student;
 }
 public void say(){
  System.out.println(student.getName()+",叫家長來一下。");
 }
}
@Configuration
class Config{
 @Value("張三") String name;
 @Bean(name = "student")
 public Student student(){
  Student student=new Student();
  student.setName(name);
  return student;
 }
 @Bean(name = "teacher")
 public Teacher teacher(){
  Teacher teacher=new Teacher();
  teacher.setStudent(student());
  return teacher;
 }
}

基于Java配置類的裝配,會將Bean的配置耦合到應(yīng)用代碼中,不推薦使用?;贘ava配置類的注解還有其它的,此處不再介紹。

使用xml文件配置Bean,是為了解耦,但隨著Bean的增多,xml文件越來越臃腫,所以一般是折中使用注解+xml文件的方式。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中方法作為參數(shù)傳遞的方式

    Java中方法作為參數(shù)傳遞的方式

    這篇文章主要介紹了Java如何讓方法作為參數(shù)傳遞,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Java實現(xiàn)打字游戲

    Java實現(xiàn)打字游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)打字游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • SpringBoot定制三種錯誤頁面及錯誤數(shù)據(jù)方法示例

    SpringBoot定制三種錯誤頁面及錯誤數(shù)據(jù)方法示例

    Spring Boot提供的默認(rèn)異常處理機制通常并不一定適合我們實際的業(yè)務(wù)場景,因此,我們通常會根據(jù)自身的需要對Spring Boot全局異常進行統(tǒng)一定制,例如定制錯誤頁面,定制錯誤數(shù)據(jù)等。本文主要介紹了SpringBoot三種自定義錯誤頁面的實現(xiàn),快來學(xué)習(xí)吧
    2021-12-12
  • 深入學(xué)習(xí)MyBatis中的參數(shù)(推薦)

    深入學(xué)習(xí)MyBatis中的參數(shù)(推薦)

    大家日常使用MyBatis經(jīng)常會遇到一些異常,想要避免參數(shù)引起的錯誤,我們需要深入了解參數(shù)。想了解參數(shù),我們首先看MyBatis處理參數(shù)和使用參數(shù)的全部過程。下面這篇文章主要給大家介紹了MyBatis中參數(shù)的的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-06-06
  • Java的函數(shù)方法詳解(含漢諾塔問題)

    Java的函數(shù)方法詳解(含漢諾塔問題)

    漢諾塔問題是一個經(jīng)典的遞歸問題,下面這篇文章主要給大家介紹了關(guān)于Java函數(shù)方法(含漢諾塔問題)的相關(guān)資料,文中通過圖文以及代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Java Socket編程(三) 服務(wù)器Sockets

    Java Socket編程(三) 服務(wù)器Sockets

    Java Socket編程(三) 服務(wù)器Sockets...
    2006-12-12
  • SpringCloud中使用Sentinel實現(xiàn)限流的實戰(zhàn)

    SpringCloud中使用Sentinel實現(xiàn)限流的實戰(zhàn)

    限流在很多地方都可以使用的到,本篇博客將介紹如何使用SpringCloud中使用Sentinel實現(xiàn)限流,從而達到服務(wù)降級的目的,感興趣的可以了解一下
    2022-01-01
  • C++排序算法之桶排序原理及實現(xiàn)詳解

    C++排序算法之桶排序原理及實現(xiàn)詳解

    這篇文章主要介紹了C++排序算法之桶排序原理及實現(xiàn)詳解, C++ 桶排序是一種線性時間復(fù)雜度的排序算法,它通過將待排序元素分配到不同的桶中,然后對每個桶中的元素進行排序,最后將所有桶中的元素按順序合并得到有序序列,需要的朋友可以參考下
    2023-10-10
  • Java中堆和棧的區(qū)別詳解

    Java中堆和棧的區(qū)別詳解

    這篇文章主要介紹了Java中堆和棧的區(qū)別詳解,所有的Java程序都運行在JVM虛擬機內(nèi)部,我們這里介紹的自然是JVM(虛擬)內(nèi)存中的堆和棧,需要的朋友可以參考下
    2015-01-01
  • github上的java項目怎么運行(面向小白)

    github上的java項目怎么運行(面向小白)

    這篇文章主要介紹了github上的java項目怎么運行(面向小白),今天從github把我以前寫的一個小demo下載下來了,第一次下載項目,摸索了一個多小時,才運行起來,需要的朋友可以參考下
    2019-06-06

最新評論