[译]15-spring 自动装配
前面的章节我们已经学习了如何使用bean元素在xml配置文件中声明一个bean.也学习了如何使用bean的子元素contructor-arg
和property进行bean的依赖项的注入.
之前bean的装配(依赖项的注入)都是我们手动进行了.我们之前使用contructor-arg元素指定使用bean的构造器参数进行依赖项
的注入;使用property元素指定使用bean的setter方法进行依赖项的注入.其实spring IOC容器支持bean的自动装配(依赖项的自
动注入).使用bean的自动装配功能可以大大缩减配置元数据的大小.
可以使用bean元素的autowire属性指定自动装配的类型,spring支持如下类型:
自动装配的类型 | 描述 |
no/default | autowire="no"指定spring不使用自动装配,需要手动装配 |
byName | 按照bean属性的名字从spring容器中找同名的bean进行注入,适用于setter注入 |
byType | 按照bean属性的类型从spring容器中找相同类型的bean进行注入,适用于setter注入 |
constructor | 按照类型装配,跟byType类似.适用于构造器参数注入 |
下面我们将分别讲解着四种装配类型
不使用自动装配-no
我们之前讲解的所有的例子都属于这种类型.在这种情况下所有bean的装配都是手动进行的.我们再用一个例子复习下
1.新建包com.tutorialspoint.autowire,并在包中新建Cat.java、Dog.java、Duck.java.后面所有例子都会用到这三个类:
- //Cat.java
- package com.tutorialspoint.autowire;
- public class Cat {
- public void sayHi(){
- System.out.println("miao miao ... ");
- }
- }
- //Dog.java
- package com.tutorialspoint.autowire;
- public class Dog {
- public void sayHi(){
- System.out.println("wang wang ... ");
- }
- }
- //Duck.java
- package com.tutorialspoint.autowire;
- public class Duck {
- public void sayHi(){
- System.out.println("ga ga ... ");
- }
- }
2.新建包com.tutorialspoint.autowire.no,并在包中新建Zoo.java,内容如下:
- package com.tutorialspoint.autowire.no;
- import com.tutorialspoint.autowire.*;
- public class Zoo {
- private Cat cat;
- private Dog dog;
- private Duck duck;
- public void setCat(Cat cat) {
- this.cat = cat;
- }
- public void setDog(Dog dog) {
- this.dog = dog;
- }
- public void setDuck(Duck duck) {
- this.duck = duck;
- }
- public void print(){
- if(cat==null){
- System.out.println("cat is null");
- }else{
- cat.sayHi();
- }
- if(dog==null){
- System.out.println("dog is null");
- }else{
- dog.sayHi();
- }
- if(duck==null){
- System.out.println("duck is null");
- }else{
- duck.sayHi();
- }
- }
- }
3.在src目录下新建autowire_no.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-3.0.xsd">
- <bean id="cat" class="com.tutorialspoint.autowire.Cat"></bean>
- <bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
- <bean id="duck" class="com.tutorialspoint.autowire.Duck"></bean>
- <bean id="zoo" class="com.tutorialspoint.autowire.no.Zoo">
- <property name="cat" ref="cat"></property>
- <property name="dog" ref="dog"></property>
- </bean>
- </beans>
4.在com.tutorialspoint.autowire.no包中新建MainApp.java.内容如下:
- package com.tutorialspoint.autowire.no;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainApp {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("autowire_no.xml");
- Zoo zoo = (Zoo) context.getBean("zoo");
- zoo.print();
- }
- }
5.运行程序,检查结果:
通过上面的程序我们可以得出如下结论:
手动装配bean,bean的所有依赖项都要在bean元素中明确指定.如果不进行指定spring容器就不会注入该属性.
按照名字进行自动装配-byName
在byName装配方式下,spring首先会反射autowire="byName"的bean,得到bean中的所有属性名(根据setter推算),然后从容
器中寻找同名的bean,最后把找到的bean注入到当前bean中.我们还是用代码说话:
1.新建包com.tutorialspoint.autowire.byname,并在包中新建Zoo.java类.内容如下:
- package com.tutorialspoint.autowire.byname;
- import com.tutorialspoint.autowire.Cat;
- import com.tutorialspoint.autowire.Dog;
- import com.tutorialspoint.autowire.Duck;
- public class Zoo {
- private Cat cat;
- private Dog dog;
- private Duck duck;
- // 自动装配并不适用于原始类型.这时候我们可以对该属性进行手动装配
- private String zooName;
- public void setZooName(String zooName) {
- this.zooName = zooName;
- }
- public void setCat(Cat cat) {
- this.cat = cat;
- }
- public void setDog(Dog dog) {
- this.dog = dog;
- }
- public void setDuck(Duck duck) {
- this.duck = duck;
- }
- public void print() {
- if (cat == null) {
- System.out.println("cat is null");
- } else {
- cat.sayHi();
- }
- if (dog == null) {
- System.out.println("dog is null");
- } else {
- dog.sayHi();
- }
- if (duck == null) {
- System.out.println("duck is null");
- } else {
- duck.sayHi();
- }
- System.out.println(zooName);
- }
- }
2.在src目录下新建autowire_byName.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-3.0.xsd">
- <!-- 名为zoo的bean在按照byName进行装配的时候,可以适配名字为cat、dog
- 的bean,不能适配名字为duck1的bean。所以最终zoo中会注入进cat和dog
- 不会注入duck. -->
- <bean id="cat" class="com.tutorialspoint.autowire.Cat"></bean>
- <bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
- <bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean>
- <bean id="zoo" class="com.tutorialspoint.autowire.byname.Zoo" autowire="byName">
- <!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
- <property name="zooName" value="international_zoo"></property>
- </bean>
- </beans>
3.在包com.tutorialspoint.autowire.byname中新建MainApp.java.内容如下:
- package com.tutorialspoint.autowire.byname;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainApp {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("autowire_byName.xml");
- Zoo zoo = (Zoo)context.getBean("zoo");
- zoo.print();
- }
- }
4.运行代码,检查结果:
分析结果可以看到cat和dog已经按照属性名字自动装配到了zoo中.duck1由于没有匹配的属性名所以没有进行装配.zooName是
我们手动进行注入的。
按照类型进行自动装配-byType
在byType装配方式下,spring首先会反射autowire="byType"的bean,得到bean属性的返回类型,然后去spring容器中按照类
型去匹配,最后把匹配到的bean注入到当前bean中.看个例子就明白了:
1.新建包com.tutorialspoint.autowire.bytype,并在包中新建Zoo.java类,内容如下:
- package com.tutorialspoint.autowire.bytype;
- import com.tutorialspoint.autowire.Cat;
- import com.tutorialspoint.autowire.Dog;
- import com.tutorialspoint.autowire.Duck;
- public class Zoo {
- private Cat cat;
- private Dog dog;
- private Duck duck;
- // 自动装配并不适用于原始类型.这时候我们可以对该属性进行手动装配
- private String zooName;
- public void setZooName(String zooName) {
- this.zooName = zooName;
- }
- public void setCat(Cat cat) {
- this.cat = cat;
- }
- public void setDog(Dog dog) {
- this.dog = dog;
- }
- public void setDuck(Duck duck) {
- this.duck = duck;
- }
- public void print() {
- if (cat == null) {
- System.out.println("cat is null");
- } else {
- cat.sayHi();
- }
- if (dog == null) {
- System.out.println("dog is null");
- } else {
- dog.sayHi();
- }
- if (duck == null) {
- System.out.println("duck is null");
- } else {
- duck.sayHi();
- }
- System.out.println(zooName);
- }
- }
2.在src目录下新建配置文件autowire_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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <!-- 名为zoo的bean在按照byType进行装配的时候,可以适配名字为cat1、dog1、duck1
- 的bean的类型。所以最终cat1、dog1、duck1会被分别注入进zoo的cat、dog、duck属性。
- 在按照类型进行装配的时候,如过有两个bean的类型符合的话,spring就不知道最终该使用哪个,这时候我们
- 可以使用primary="true"告诉spring优先使用本bean
- -->
- <bean id="cat1" class="com.tutorialspoint.autowire.Cat" primary="true"></bean>
- <bean id="cat2" class="com.tutorialspoint.autowire.Cat"></bean>
- <bean id="dog1" class="com.tutorialspoint.autowire.Dog"></bean>
- <bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean>
- <bean id="zoo" class="com.tutorialspoint.autowire.bytype.Zoo" autowire="byType">
- <!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
- <property name="zooName" value="international_zoo"></property>
- </bean>
- </beans>
3.在包com.tutorialspoint.autowire.bytype中新建MainApp.java。内容如下:
- package com.tutorialspoint.autowire.bytype;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainApp {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("autowire_byType.xml");
- Zoo zoo = (Zoo)context.getBean("zoo");
- zoo.print();
- }
- }
4.运行程序,检查结果:
构造器参数类型自动装配-constructor
在constructor自动装配模式下,spring首先会反射bean的构造函数,得出构造函数的参数的类型,然后起spring容器中匹配合适的
类型的bean,最后使用构造器参数注入的方法把符合的bean注入到当前bean中。看代码:
1.新建包com.tutorialspoint.autowire.constructor,并在包中新建Zoo.java。内容如下:
- package com.tutorialspoint.autowire.constructor;
- import com.tutorialspoint.autowire.*;
- public class Zoo {
- private Cat cat;
- private Dog dog;
- private Duck duck;
- private String zooName;
- public Zoo(Cat cat, Dog dog, Duck duck, String zooName) {
- this.cat = cat;
- this.dog = dog;
- this.duck = duck;
- this.zooName = zooName;
- }
- public void print() {
- if (cat == null) {
- System.out.println("cat is null");
- } else {
- cat.sayHi();
- }
- if (dog == null) {
- System.out.println("dog is null");
- } else {
- dog.sayHi();
- }
- if (duck == null) {
- System.out.println("duck is null");
- } else {
- duck.sayHi();
- }
- System.out.println(zooName);
- }
- }
2.在src目录下新建autowire_constructor.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-3.0.xsd">
- <!-- constructor跟byType十分相似.
- 名为zoo的bean在按照constructor进行装配的时候,可以适配名字为cat1、dog1、duck1
- 的bean的类型。所以最终cat1、dog1、duck1会被分别注入进zoo的cat、dog、duck属性(使用
- 构造器参数进行注入)。
- 在按照constructor进行装配的时候,如过有两个bean的类型符合的话,spring就不知道最终该使用哪个,这时候我们
- 可以使用primary="true"告诉spring优先使用本bean
- -->
- <bean id="cat1" class="com.tutorialspoint.autowire.Cat" primary="true"></bean>
- <bean id="cat2" class="com.tutorialspoint.autowire.Cat"></bean>
- <bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
- <bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean>
- <bean id="zoo" class="com.tutorialspoint.autowire.constructor.Zoo" autowire="constructor">
- <!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
- <constructor-arg name="zooName" value="international_zoo"></constructor-arg>
- </bean>
- </beans>
3.在com.tutorialspoint.autowire.constructor包中新建MainApp.java。内容如下:
- package com.tutorialspoint.autowire.constructor;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainApp {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("autowire_constructor.xml");
- Zoo zoo = (Zoo)context.getBean("zoo");
- zoo.print();
- }
- }
4.运行程序,检查结果:
如果使用sping的自动装配,本人不推荐使用xml的配置方式.最好使用注解的配置方式。原因如下:
1.基于xml的自动装配粒度态度。默认会装配所有符合条件的bean.不能指定哪个属性不进行自动装配
2.不能指定哪些属性必须进行装配,否则抛出异常.
以上两点使用spring的注解配置元数据都是可以做到的。我们下节就讲解spring注解配置元数据。
[译]15-spring 自动装配的更多相关文章
- Spring自动装配(二)
为什么Spring要支持Autowire(自动装配) 先写几个类,首先定义一个Animal接口表示动物: 1 public interface Animal { 2 3 public void eat ...
- Spring 自动装配 Bean
Spring3系列8- Spring 自动装配 Bean 1. Auto-Wiring ‘no’ 2. Auto-Wiring ‘byName’ 3. Auto-Wiri ...
- spring 自动装配 default-autowire="byName/byType"
<PRE class=html name="code">spring 自动装配 default-autowire="byName/byType" ...
- Spring自动装配Bean详解
1. Auto-Wiring ‘no’ 2. Auto-Wiring ‘byName’ 3. Auto-Wiring ‘byType 4. Auto-Wirin ...
- Spring自动装配----注解装配----Spring自带的@Autowired注解
Spring自动装配----注解装配----Spring自带的@Autowired注解 父类 package cn.ychx; public interface Person { public voi ...
- Spring系列七:Spring 自动装配
相思相见知何日?此时此夜难为情. 概述 在Spring框架中,在配置文件中声明bean的依赖关系是一个很好的做法,因为Spring容器能够自动装配协作bean之间的关系.这称为spring自动装配. ...
- Spring自动装配歧义性笔记
Spring自动装配歧义性笔记 如果系统中存在两个都实现了同一接口的类,Spring在进行@Autowired自动装配的时候,会选择哪一个?如下: // 一下两个类均被标记为bean @Compone ...
- Spring 自动装配;方法注入
通过配置defalut—autowire属性,Spring IOC容器可以自动为程序注入Bean:默认是no(不启用自动装配). default—autowire的类型有: byName:通过名称自动 ...
- spring自动装配
spring提供了自动装配(autowiring)和自动检测(autodiscovery)用来减少XML的配置数量. 自动装配bean属性 byName——把与Bean的属性具有相同名字(或ID)的其 ...
- Spring自动装配与扫描注解
1 javabean的自动装配 自动注入,减少xml文件的配置信息. <?xml version="1.0" encoding="UTF-8"?> ...
随机推荐
- centos 开启http代理tinyproxy
一.前言 就算有一些公司想到要进行压力测试也是用一些微软,官网出的一些软件,一个ip发起很多访问.等有一天黑客攻击来了发现还是顶不住.华盟君认为知此知彼才是压力测试的关键点,应当模拟黑客手法进行压力测 ...
- c#winform初学习
不用思维导图了直接拍照笔记吧..参考视频:传智播客.net第十四天,参考图书c#图解教程第四版(人民邮电出版社) 对对象初始化赋值 工具箱中的每一个控件都相当于一个类 在窗体中拖一个控件就相当于new ...
- GPU计算的后CUDA时代-OpenACC(转)
在西雅图超级计算大会(SC11)上发布了新的基于指令的加速器并行编程标准,既OpenACC.这个开发标准的目的是让更多的编程人员可以用到GPU计算,同时计算结果可以跨加速器使用,甚至能用在多核CPU上 ...
- Firefox 修改User Agent
Android 版 Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML ...
- loss 和accuracy的关系梳理
最近打算总结一下这部分东西,先记录留个脚印.
- Apache 负载均衡 端口转发 配置
转载自:https://blog.csdn.net/snihcel/article/details/38844323 [端口转发配置] 通过http_proxy做tomcat的端口转发: ...
- Java的“Goto”与标签
goto在Java中是一个保留字,但在语言中并没有用到它:Java没有goto.但是,Java也能完成一些类似于跳转的操作,主要是依靠:标签. 为什么要使用标签 在迭代语句中,我们可以使用break和 ...
- mysql指定id默认第一
有个需求 家庭创建人要默认排第一,刚开始用加入家庭的时间排序可以 好简单, 后来加了一个需求 家庭创建人可以转移,结果按时间排序就不行了,又不想去写循环重新排序 就各种百度, 等于就是指定ID排最后 ...
- linux环境下nginx配置
1.反向代理配置 # nginx/conf/nginx.conf
- 7-4 python 接口开发(提供mock服务)
1.登录接口开发(数据存在数据库中) 接口开发做mock(模拟功能) tools.py import pymysql def my_db(sql): conn = pymysql.connect(h ...