zoukankan      html  css  js  c++  java
  • Spring(九):Spring配置Bean(二)自动装配的模式、Bean之间的关系

    XML配置里的Bean自动装配

    Spring IOC容器可以自动装配Bean,需要做的仅仅是在<bean>的autowire属性里指定自动装配的模式,模式包含:byType,byName,constructor

    举例:

    常规用法:

    Member.java

    package com.dx.spring.bean.autowire;
    
    public class Member {
        private String name;
        private int age;
        private Address address;
        private Work work;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public Work getWork() {
            return work;
        }
    
        public void setWork(Work work) {
            this.work = work;
        }
    
        @Override
        public String toString() {
            return "Member [name=" + name + ", age=" + age + ", address=" + address + ", work=" + work + "]";
        }
    
    }
    View Code

    Address.java

    package com.dx.spring.bean.autowire;
    
    public class Address {
        private String city;
        private String area;
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getArea() {
            return area;
        }
    
        public void setArea(String area) {
            this.area = area;
        }
    
        @Override
        public String toString() {
            return "Address [city=" + city + ", area=" + area + "]";
        }
    
    }
    View Code

    Work.java

    package com.dx.spring.bean.autowire;
    
    public class Work {
        private String company;
        private int money;
    
        public String getCompany() {
            return company;
        }
    
        public void setCompany(String company) {
            this.company = company;
        }
    
        public int getMoney() {
            return money;
        }
    
        public void setMoney(int money) {
            this.money = money;
        }
    
        @Override
        public String toString() {
            return "Work [company=" + company + ", money=" + money + "]";
        }
    
    }
    View Code

    bean-autowire.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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" class="com.dx.spring.bean.autowire.Address">
            <property name="city" value="beijing"></property>
            <property name="area" value="huilongguan"></property>
        </bean>
    
        <bean id="work" class="com.dx.spring.bean.autowire.Work">
            <property name="company" value="baidu"></property>
            <property name="money" value="80000"></property>
        </bean>
    
        <bean id="member" class="com.dx.spring.bean.autowire.Member"
            p:name="Rose" p:age="27" p:address-ref="address" p:work-ref="work"></bean>
    
    </beans>

    Main.java

    package com.dx.spring.bean.autowire;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext cxt = new ClassPathXmlApplicationContext("bean-autowire.xml");
            Member member = (Member) cxt.getBean("member");
            System.out.println(member);
        }
    }
    View Code

    测试打印结果:

    Member [name=Rose, age=27, address=Address [city=beijing, area=huilongguan], work=Work [company=baidu, money=80000]]

    1)byName(根据名称自动装配):

    必须将目标Bean的名称和属性名设置的完成相同。

    修改常规用法中的bean-autowire.xml:

        <bean id="member" class="com.dx.spring.bean.autowire.Member"
            p:name="Rose" p:age="27" autowire="byName"></bean>

    此时,如果修改work bean的名字为work2

        <bean id="work2" class="com.dx.spring.bean.autowire.Work">
            <property name="company" value="baidu"></property>
            <property name="money" value="80000"></property>
        </bean>

    则Main.java调用时,无法匹配上work属性:

    Member [name=Rose, age=27, address=Address [city=beijing, area=huilongguan], work=null]

    2)byType(根据类型自动装配):

    若IOC容器中有多个与目标Bean类型一致的Bean,在这种情况下,Spring将无法判定哪个Bean最合适该属性,所以不能执行自动装配。

        <bean id="member" class="com.dx.spring.bean.autowire.Member"
            p:name="Rose" p:age="27" autowire="byType"></bean>

    此时如果在bean-autowire.xml中包含多个Work的bean时:

    <?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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" class="com.dx.spring.bean.autowire.Address">
            <property name="city" value="beijing"></property>
            <property name="area" value="huilongguan"></property>
        </bean>
    
        <bean id="work" class="com.dx.spring.bean.autowire.Work">
            <property name="company" value="baidu"></property>
            <property name="money" value="80000"></property>
        </bean>
        <bean id="work3" class="com.dx.spring.bean.autowire.Work">
            <property name="company" value="jd"></property>
            <property name="money" value="90000"></property>
        </bean>
        
        <bean id="member" class="com.dx.spring.bean.autowire.Member"
            p:name="Rose" p:age="27" autowire="byType"></bean>
    
    </beans>

    此时运行时,将会抛出异常:

    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
    Error creating bean with name 'member' defined in class path resource [bean-autowire.xml]:
    Unsatisfied dependency expressed through bean property 'work';
    nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
    No qualifying bean of type 'com.dx.spring.bean.autowire.Work' available: expected single matching bean but found 2: work,work3

    3)constructor(通过构造器自动装配):

    当Bean中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用。

    XML配置里的Bean自动装配缺点

    1)在bean配置文件里设置autowire属性进行自动装配将会装配bean所有属性。然而,若只希望装配个别属性是,autowire属性就不够灵活了。

    2)autowire属性要么根据类型自动装配,要么根据名称自动装配,不能两者兼而有之。

    3)一般情况下,在实际项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力。

    bean之间的关系:继承;依赖。  

    bean之间的关系:继承

    1)Spring允许继承bean的配置,被集成的bean称为父bean。继承这个父bean的bean称为子bean。

    2)子bean从父bean中继承配置,包括bean的属性配置

    3)父bean可以作为配置模版,也可以作为bean实例。若只想把父bean作为模版,可以设置<bean>的abstract属性为true,这样Spring将不会实例化这个bean。

    4)并不是<bean>元素里的所有属性都会被继承。比如:autowire,abstract等。

    5)也可以忽略父bean的class属性,让子bean指定自己的类,而共享相同的属性配置,但此时abstract必须设为true。

    常规示例:有两个address bean,此时用法如下:

    bean-relation-dependence.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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="address" class="com.dx.spring.beans.relation_dependence.Address"
            p:city="Beijing" p:street="HuiLongGuan">
        </bean>
        <bean id="address2" class="com.dx.spring.beans.relation_dependence.Address"
            p:city="Beijing" p:street="ZhongGuanCun">
        </bean>    
    </beans>

    Adress.java

    package com.dx.spring.beans.relation_dependence;
    
    public class Address {
        private String city;
        private String street;
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getStreet() {
            return street;
        }
    
        public void setStreet(String street) {
            this.street = street;
        }
    
        @Override
        public String toString() {
            return "Address [city=" + city + ", street=" + street + "]";
        }
    
    }
    View Code

    Client.java

    package com.dx.spring.beans.relation_dependence;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Client {
        public static void main(String[] args) {
            ApplicationContext cxt = new ClassPathXmlApplicationContext("bean-relation-dependence.xml");
            Address address = (Address) cxt.getBean("address");
            System.out.println(address);
    
            Address address2 = (Address) cxt.getBean("address2");
            System.out.println(address2);
        }
    }

    a)实际上address2是可以通过继承address bean的,修改bean-relation-dependence.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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" class="com.dx.spring.beans.relation_dependence.Address"
            p:city="Beijing" p:street="HuiLongGuan">
        </bean>
    
        <bean id="address2" p:street="ZhongGuanCun" parent="address">
        </bean>
        
    </beans>

    b)可以把父类bean配置为一个模版(抽象)bean:

    <?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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" p:city="Beijing" p:street="HuiLongGuan" class="com.dx.spring.beans.relation_dependence.Address" abstract="true">
        </bean>
    
        <bean id="address2" p:street="ZhongGuanCun"
            class="com.dx.spring.beans.relation_dependence.Address" parent="address">
        </bean>
    
    </beans>

    此时address这个bean是不能够被实例化的,否则会抛出异常。

    package com.dx.spring.beans.relation_dependence;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Client {
        public static void main(String[] args) {
            ApplicationContext cxt = new ClassPathXmlApplicationContext("bean-relation-dependence.xml");
            // 当把address bean的属性设置abstract="true"时,该bean不能被实例化,否则会抛出异常。
            // Address address = (Address) cxt.getBean("address");
            // System.out.println(address);
    
            Address address2 = (Address) cxt.getBean("address2");
            System.out.println(address2);
        }
    }

    c)也可以把父类bean配置为一个无class属性的模版(抽象)bean:

    <?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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="address" p:city="Beijing" p:street="HuiLongGuan" abstract="true">
        </bean>
        <bean id="address2" p:street="ZhongGuanCun"
            class="com.dx.spring.beans.relation_dependence.Address" parent="address">
        </bean>
    </beans>

    备注:如果一个bean的class属性没有被指定,则该bean必须为一个抽象bean。

    bean之间的关系:依赖

    1)spring允许用户通过depends-on属性设定bean前置依赖的bean,前置依赖的bean会在本bean实例化之前创建好。

    2)如果前置依赖于多个bean,则可以通过逗号、空格的方式配置bean的名称

    bean-relation-dependence.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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" p:city="Beijing" p:street="HuiLongGuan"
            abstract="true">
        </bean>
    
        <bean id="address2" p:street="ZhongGuanCun"
            class="com.dx.spring.beans.relation_dependence.Address" parent="address">
        </bean>
        
        <bean id="car" class="com.dx.spring.beans.relation_dependence.Car"
            p:brand="Audi" p:corp="Shanghai" p:price="400000" p:maxSpeed="260"></bean>
            
        <bean id="person" class="com.dx.spring.beans.relation_dependence.Person"
            p:name="RoseGun" p:age="35" p:address-ref="address2" depends-on="car"></bean>
    </beans>

    此时,如果depends-on的car不存在,则会抛出异常。

  • 相关阅读:
    771. Jewels and Stones
    706. Design HashMap
    811. Subdomain Visit Count
    733. Flood Fill
    117. Populating Next Right Pointers in Each Node II
    250. Count Univalue Subtrees
    94. Binary Tree Inorder Traversal
    116. Populating Next Right Pointers in Each Node
    285. Inorder Successor in BST
    292. Nim Game Java Solutin
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/9043846.html
Copyright © 2011-2022 走看看