zoukankan      html  css  js  c++  java
  • Spring -- Bean自己主动装配&Bean之间关系&Bean的作用域

    对于学习spring有帮助的站点:http://jinnianshilongnian.iteye.com/blog/1482071

    Bean的自己主动装配

    Spring IOC 容器能够自己主动装配 Bean. 需要做的仅仅是在 的 autowire 属性里指定自己主动装配的模式
    有以下几种自己主动装配的类型:

    • byType(依据类型自己主动装配): 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这样的情况下, Spring
      将无法判定哪个 Bean 最合适该属性, 所以不能执行自己主动装配.
    • byName(依据名称自己主动装配): 必须将目标 Bean 的名称和属性名设置的全然同样.
    • constructor(通过构造器自己主动装配): 当 Bean 中存在多个构造器时, 此种自己主动装配方式将会非常复杂. 不推荐使用

    首先我们先来看一个手动装配的样例,
    文件夹结构
    这里写图片描写叙述

    先创建两个实体Bean

    package com.gp.spring.autowire;
    
    public class Person {
        private String name;
        private Address address;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", address=" + address + "]";
        }
    
    }
    
    package com.gp.spring.autowire;
    
    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 + "]";
        }
    
    }
    

    再创建IOC配置文件

    <?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:util="http://www.springframework.org/schema/util" 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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="address" class="com.gp.spring.autowire.Address" p:city="beijing" p:street="haidian"></bean> <bean id="person" class="com.gp.spring.autowire.Person" p:name="Alis" p:address-ref="address"></bean> </beans>

    測试代码

    package com.gp.spring.autowire;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "autowired.xml");
            Person p = (Person) ctx.getBean("person");
    
            System.out.println(p);
        }
    }
    

    输出结果

    Person [name=Alis, address=Address [city=beijing, street=haidian]]


    以下我们来看一下是怎样进行自己主动装配的
    改动配置文件

        <bean id="address" class="com.gp.spring.autowire.Address"
            p:city="beijing" p:street="haidian"></bean>
    
        <bean id="person" class="com.gp.spring.autowire.Person"
            p:name="Alis" autowire="byName"></bean>

    添加代码autowire=”byName”,使用byName的方式进行自己主动匹配。


    它就会依据person类中的setAddress属性匹配名为address的bean。


    同理可知,byType匹配方式,匹配与setAddress类型一直的bean。


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

    • 在 Bean 配置文件中设置 autowire 属性进行自己主动装配将会装配 Bean 的全部属性. 然而, 若仅仅希望装配个别属性时,
      autowire 属性就不够灵活了.
    • autowire 属性要么依据类型自己主动装配, 要么依据名称自己主动装配, 不能两者兼而有之.
    • 普通情况下,在实际的项目中非常少使用自己主动装配功能,由于和自己主动装配功能所带来的优点比起来。明白清晰的配置文档更有说服力一些

    Bean的继承关系

    • Spring 同意继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean
    • 子 Bean 从父 Bean 中继承配置, 包含 Bean 的属性配置
    • 子Bean也能够覆盖从父Bean中继承过来的属性
    • 父 Bean 能够作为配置模板, 也能够作为 Bean 实例. 若仅仅想把父 Bean 作为模板, 能够设置 bean的abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean

    来看下以下这段代码

        <bean id="address1" class="com.gp.spring.autowire.Address"
            p:city="鸡西" p:street="南岗"></bean>
    
        <bean id="address2" class="com.gp.spring.autowire.Address"
            p:city="鸡西" p:street="电台路"></bean>
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "context_relate.xml");
            Address address = (Address) ctx.getBean("address1");
            System.out.println(address);
    
            address = (Address) ctx.getBean("address2");
            System.out.println(address);
        }

    输出结果

    Address [city=鸡西, street=南岗]
    Address [city=鸡西, street=电台路]

    非常easy的属性注入,你是否注意到再配置文件中,注入的两条信息。大部分内容是同样的,比方同样的Bean,同样的值。

    这里我们能够用一个Bean继承的做法。来简化配置。例如以下

        <bean id="address1" class="com.gp.spring.autowire.Address"
            p:city="鸡西" p:street="南岗"></bean>
    
        <bean id="address2" p:street="电台路" parent="address1"></bean>

    这里用到了parent,继承自address1的Bean。然后我们在重写我们要改动的内容。


    抽象Bean(abstract=”true”)

    抽象的Bean是不同意被实例化的,我们看一个错误的代码

        <bean id="address1" class="com.gp.spring.autowire.Address"
            p:city="鸡西" p:street="南岗" abstract="true"></bean>
    
        <bean id="address2" p:street="电台路" parent="address1"></bean>

    address1添加了abstract=”true”表示为抽象Bean

        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "context_relate.xml");
            Address address = (Address) ctx.getBean("address1");
            System.out.println(address);
    
            address = (Address) ctx.getBean("address2");
            System.out.println(address);
        }

    执行測试方法

    我们会看到以下异常,意思为抽象类是不许被实现的。

    Exception in thread “main” org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name ‘address1’: Bean definition is abstract

    所以我们去掉address1的实现就可以。

        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "context_relate.xml");
    //      Address address = (Address) ctx.getBean("address1");
    //      System.out.println(address);
    
            Address address = (Address) ctx.getBean("address2");
            System.out.println(address);
        }

    通常抽象Bean使用方法,不指定详细的类,在其继承的子类中指定class。例如以下

        <bean id="address1" p:city="鸡西" p:street="南岗" abstract="true"></bean>
    
        <bean id="address2" class="com.gp.spring.autowire.Address"
            p:street="电台路" parent="address1"></bean>
    
        <bean id="address3" class="com.gp.spring.autowire.Address"
            p:street="和平大街" parent="address1"></bean>

    依赖Bean的配置

    当我们在注入Bean的信息的时候,假设要求某些信息必须录入,则这就是Bean的依赖。


    比方我们注入一个person类信息,当中person有一个address的属性,前提要求address必需要被注入数据,这样这个人才有地址,也就是person依赖address

    以下我们来看看代码

        <bean id="address" class="com.gp.spring.autowire.Address"
            p:street="和平大街" p:city="鸡西"></bean>
    
        <bean id="person" class="com.gp.spring.autowire.Person" 
            p:name="pengpeng" depends-on="address"></bean>

    输出内容

    Person [name=pengpeng, address=null]

    假设我们去掉address

        <!-- 
        <bean id="address" class="com.gp.spring.autowire.Address"
            p:street="和平大街" p:city="鸡西"></bean>
         -->
        <bean id="person" class="com.gp.spring.autowire.Person" 
            p:name="pengpeng" depends-on="address"></bean>

    会抛出一下异常

    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘address’ is defined

    假设前置依赖于多个 Bean,则能够通过逗号,空格或的方式配置 Bean 的名称


    Bean的作用域

    Bean的作用域能够理解为IOC容器中的Bean他的作用范围。我们通过以上的内容了解到获取到一个bean的信息通过以下方式

    Address address1 = (Address) ctx.getBean("address");

    那比方如今我获取多个的时候会是什么样子的呢。我们做了下測试

        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "context_relate.xml");
            Address address1 = (Address) ctx.getBean("address");
            Address address2 = (Address) ctx.getBean("address");
            System.out.println(address1 == address2);
        }

    输出结果:true
    可知IOC容器中的Bean都是单实例的。
    我们能够通过scope来配置Bean的作用域。眼下有四种
    这里写图片描写叙述
    当中主要用的singleton、prototype。

    默认情况是singleton。
    以下改动IOC配置

        <bean id="address" class="com.gp.spring.autowire.Address"
            p:street="电台路" p:city="鸡西" scope="prototype"></bean>

    输出结果:false
    另外两个request、session在web的应用开发中使用。兴许用到的时候单独介绍。


    使用外部属性文件

    我们在开发的时候会使用spring注入JDBC的连接池信息。代码例如以下

    <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"
        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
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
    
        <context:property-placeholder location="classpath:db.properties"/>
    
        <bean id="db" class="com.gp.spring.jdbc.DataSource">
            <property name="userName" value="${username}"></property>
            <property name="password" value="${password}"></property>
        </bean>
    </beans>

    这里context:property-placeholder引入外部文件。然后通过${}方式获取信息。

    db.properties代码例如以下

    username=root
    password=123456
  • 相关阅读:
    uva 550
    uva 10110
    uva 10014
    uva 10177
    uva 846
    Dear Project Manager, I Hate You
    创业型软件公司的心得
    架构设计的心得
    程序员常去的103个网站
    66个经典源码网站
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7205163.html
Copyright © 2011-2022 走看看