您好,登錄后才能下訂單哦!
Bean常用的裝配方式有3種:
基于xml的裝配
在xml文件中配置Bean。
如果依賴很多,xml配置文件會很臃腫,后期維護、升級不方便。自動裝配可解決這一問題。
基于xml的自動裝配
在<bean>中使用autowired屬性完成依賴的自動裝配,不再使用<property>手動注入setter方法中的依賴,簡化了配置,減少了xml中的代碼量。
autowire屬性的屬性值:
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自動裝配的執行過程:在這個Bean的定義中,找到setter方法,這里是setStudent(),其name是student(set后面部分提出來,變成Camel寫法),根據這個name(student)找打到id/name是student的Bean實例,將這個實例自動注入。
所以對<bean>的id/name、setter方法的命名有嚴格要求。
原本是要用<property name ref="" />子元素注入依賴的,如果依賴較多,會寫一大堆<property>子元素。自動裝配,不管這個一Bean有多少個依賴,一句代碼搞定,減少了代碼量,由Spring容器自動注入依賴。但Spring容器要做更多的工作,裝配速度會變慢。
說明:自動裝配只能完成setter形式的依賴注入,不能完成構造器方式的依賴注入,且只能注入其它Bean,不能注入String、數組、集合等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
根據要注入的Bean的類型來自動裝配。
在上面的例子中,setStudent(Student student),要注入的依賴是Student類型的實例。
byType自動裝配的執行過程:在這個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()+",叫家長來一下。"); } }
需要用構造器注入依賴,Spring容器會自動根據構造器中參數類型,用byType方式注入對應類型的依賴。
只能有一個構造器,否則Spring容器不知道使用哪個構造器。
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>中設置默認的自動裝配方式,在需要使用自動裝配的<bean>指定autowire="default",這樣該<bean>使用的自動裝配方式就是<beans>中設置的默認方式。
統一了應用的自動裝配方式。
基于注解的裝配
基于xml裝配的方式,如果<bean>很多,xml文件依然很臃腫。基于注解的裝配解決了這一問題。
基于注解的裝配是最常用的。
Spring常用的注解:
記法: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方法,也不必寫構造器。在依賴的對象上添加@Autowired注解(當然也可以在setter方法上寫),即按照類型自動裝配依賴。
上面在Student類型的依賴上添加了@Autowired注解,會自動在Spring容器中,找到Student類型的Bean,注入。相當于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 https://www.springframework.org/schema/context/spring-context.xsd"> <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容器根據這個value找到id/name為vBean,注入。
可簡寫為@Qualifier("student")。
示例 @Resource
class Teacher{ @Resource(name = "student") private Student student; public void say(){ System.out.println(student.getName()+",叫家長來一下。"); } }
先根據name找到Spring容器中name/id為student的Bean,注入。即優先以getName方式。
如果找不到name/id為指定值的Bean,或缺省name直接寫@Resource,則以默認的getName方式:寫在字段上默認name為成員變量名(student),寫在setter方法上默認為set后面部分得Camel寫法,比如setStudent()默認name為student。
如果還是找不到依賴的Bean,則以byType方式注入。
說明
Spring常用的其它注解
前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個注解的作用相當于<bean class="" />。
標注了這4個注解的類,Spring會自動在xml中把這個類配置為Bean,就是說在xml中不必寫<bean class="" />。
但只能是<bean class="" />這樣基礎的配置,如果要<constructor-arg>、<property>傳遞Java自帶類型的參數,或其他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容器做更多的工作,所以創建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; //創建一個成員變量,相當于String name="張三"; @Bean(name = "student") //配置一個Bean,相當于xml中的一個<bean> public Student student(){ Student student=new Student(name); //創建并返回Bean的實例。 return student; } @Bean(name = "teacher") public Teacher teacher(){ return new Teacher(student()); //創建并返回Bean的實例,因為寫了構造器,所以可以直接構造器注入依賴。可直接調用本類中的其它方法創建依賴的實例,注入。 } } public class Test { public static void main(String[] args) { ApplicationContext applicationContext=new AnnotationConfigApplicationContext(Config.class); //注意,和xml配置不同。參數是配置類。 Teacher teacher=applicationContext.getBean("teacher",Teacher.class); teacher.say(); } }
上面的例子是通過構造器初始化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的配置耦合到應用代碼中,不推薦使用。基于Java配置類的注解還有其它的,此處不再介紹。
使用xml文件配置Bean,是為了解耦,但隨著Bean的增多,xml文件越來越臃腫,所以一般是折中使用注解+xml文件的方式。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。