Spring学习--xml 中 Bean 的自动装配

简介

    Spring IOC 容器可以自动装配 Bean。 只要在 <bean> 的 autowire 属性里指定自动装配的模式。

  1. byName(根据名称自动装配):必须将目标 Bean 的名称和当前 Bean 指定的类中的 setter 名称相匹配。
  2. byType(根据类型自动装配):必须目标 Bean 的类型和当前 Bean 的类型相匹配。
  3. Constructor(构造函数自动装配):比较复杂,不推荐使用。

名称自动装配

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="car" class="com.itdjx.spring.beans.aotuwire.Car" p:brand="Baoma" p:price="230000" />
 8     <bean id="address" class="com.itdjx.spring.beans.aotuwire.Address" p:city="Dalian" p:street="ShaHeKou"/>
 9     <bean id="person" class="com.itdjx.spring.beans.aotuwire.Person" p:name="Tom" autowire="byName"/>
10 
11 </beans>
 1 package com.itdjx.spring.beans.aotuwire;
 2 
 3 /**
 4  * @author Wáng Chéng Dá
 5  * @create 2017-03-01 10:59
 6  */
 7 public class Car {
 8 
 9     private String brand;
10     private double price;
11 
12     public String getBrand() {
13         return brand;
14     }
15 
16     public void setBrand(String brand) {
17         this.brand = brand;
18     }
19 
20     public double getPrice() {
21         return price;
22     }
23 
24     public void setPrice(double price) {
25         this.price = price;
26     }
27 
28     @Override
29     public String toString() {
30         return "Car{" +
31                 "brand='" + brand + '\'' +
32                 ", price=" + price +
33                 '}';
34     }
35 }
 1 package com.itdjx.spring.beans.aotuwire;
 2 
 3 /**
 4  * @author Wáng Chéng Dá
 5  * @create 2017-03-01 10:59
 6  */
 7 public class Address {
 8 
 9     private String city;
10 
11     private String street;
12 
13     public String getCity() {
14         return city;
15     }
16 
17     public void setCity(String city) {
18         this.city = city;
19     }
20 
21     public String getStreet() {
22         return street;
23     }
24 
25     public void setStreet(String street) {
26         this.street = street;
27     }
28 
29     @Override
30     public String toString() {
31         return "Address{" +
32                 "city='" + city + '\'' +
33                 ", street='" + street + '\'' +
34                 '}';
35     }
36 }
 1 package com.itdjx.spring.beans.aotuwire;
 2 
 3 /**
 4  * @author Wáng Chéng Dá
 5  * @create 2017-03-01 10:59
 6  */
 7 public class Person {
 8 
 9     private String name;
10 
11     private Address address;
12 
13     private Car car;
14 
15     public String getName() {
16         return name;
17     }
18 
19     public void setName(String name) {
20         this.name = name;
21     }
22 
23     public Address getAddress() {
24         return address;
25     }
26 
27     public void setAddress(Address address) {
28         this.address = address;
29     }
30 
31     public Car getCar() {
32         return car;
33     }
34 
35     public void setCar(Car car) {
36         this.car = car;
37     }
38 
39     @Override
40     public String toString() {
41         return "Person{" +
42                 "name='" + name + '\'' +
43                 ", address=" + address +
44                 ", car=" + car +
45                 '}';
46     }
47 }
 1 package com.itdjx.spring.beans.aotuwire;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 /**
 7  * @author Wáng Chéng Dá
 8  * @create 2017-03-01 11:05
 9  */
10 public class Main {
11 
12     public static void main(String[] args) {
13         ApplicationContext app = new ClassPathXmlApplicationContext("beans-aotuwire.xml");
14         Person person = (Person) app.getBean("person");
15         System.out.println(person);
16     }
17 }

 

控制台输出:

Person{name='Tom', address=Address{city='Dalian', street='ShaHeKou'}, car=Car{brand='Baoma', price=230000.0}}

 

若修改配置文件中的 address 为 address1 :

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="car" class="com.itdjx.spring.beans.aotuwire.Car" p:brand="Baoma" p:price="230000" />
 8     <bean id="address1" class="com.itdjx.spring.beans.aotuwire.Address" p:city="Dalian" p:street="ShaHeKou"/>
 9     <bean id="person" class="com.itdjx.spring.beans.aotuwire.Person" p:name="Tom" autowire="byName"/>
10 
11 </beans>

 

控制台输出:

Person{name='Tom', address=null, car=Car{brand='Baoma', price=230000.0}}

出现这种状况说明自动装配没有匹配到 address 对象。id="address" 与 Person 中的 setAdress() 方法匹配。

 

 类型自动装配

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="car" class="com.itdjx.spring.beans.aotuwire.Car" p:brand="Baoma" p:price="230000" />
 8     <bean id="address1" class="com.itdjx.spring.beans.aotuwire.Address" p:city="Dalian" p:street="ShaHeKou"/>
 9     <bean id="person" class="com.itdjx.spring.beans.aotuwire.Person" p:name="Tom" autowire="byType"/>
10 
11 </beans>

 

控制台输出:

Person{name='Tom', address=Address{city='Dalian', street='ShaHeKou'}, car=Car{brand='Baoma', price=230000.0}}

 

 若是多定义几个相同的类 , 程序会出现异常。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="car" class="com.itdjx.spring.beans.aotuwire.Car" p:brand="Baoma" p:price="230000" />
 8     <bean id="address1" class="com.itdjx.spring.beans.aotuwire.Address" p:city="Dalian" p:street="ShaHeKou"/>
 9     <bean id="address" class="com.itdjx.spring.beans.aotuwire.Address" p:city="ShenYang" p:street="Dadong"/>
10     <bean id="person" class="com.itdjx.spring.beans.aotuwire.Person" p:name="Tom" autowire="byType"/>
11 
12 </beans>

 

控制台输出:

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'person' defined in class path resource [beans-aotuwire.xml]: Unsatisfied dependency expressed through bean property 'address'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itdjx.spring.beans.aotuwire.Address' available: expected single matching bean but found 2: address1,address
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'person' defined in class path resource [beans-aotuwire.xml]: Unsatisfied dependency expressed through bean property 'address'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itdjx.spring.beans.aotuwire.Address' available: expected single matching bean but found 2: address1,address
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1357)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1249)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.itdjx.spring.beans.aotuwire.Main.main(Main.java:13)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itdjx.spring.beans.aotuwire.Address' available: expected single matching bean but found 2: address1,address
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1342)
... 13 more

 

xml 中 Bean 自动装配的缺点

  1. 在 Bean 配置文件里设置 autowire 属性进行自动装配将会装配 Bean 的所有属性。然而 , 若只希望装配个别属性时 , autowire 属性就不够灵活了。
  2. autowire 属性要么根据类型自动装配 , 要么根据名称自动装配 , 不能二者兼有。

 

posted @ 2017-03-01 11:15  Chinda  阅读(1064)  评论(0编辑  收藏  举报