• 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不存在,则会抛出异常。

  • 相关阅读:
    halcon三种模板匹配方法
    线阵相机与面阵相机的区别
    完整性检测
    halcon读取一张照片,并转化为灰度图像
    halcon车牌的识别
    HALCON学习之条形码实时扫描
    开关引脚测量
    ip sensor芯片级解决方案
    ip camera芯片级解决方案
    Parallel For Bug in static constructor
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/9043846.html
Copyright © 2020-2023  润新知