Spring4深入理解IOC&DI02----Bean配置--自动装配、bean之间的继承与依赖、使用外部属性文件

参考代码下载github:https://github.com/changwensir/java-ee/tree/master/spring4

一、XML 配置里的 Bean 自动装配

  --Spring IOC 容器可以自动装配 Bean. 需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式
  --byType(根据类型自动装配): 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这种情况下, Spring 将无法判定哪个 Bean 最合适该属性, 所以不能执行自动装配.
  --byName(根据名称自动装配): 必须将目标 Bean 的名称和属性名设置的完全相同.
  --constructor(通过构造器自动装配): 当 Bean 中存在多个构造器时, 此种自动装配方式将会很复杂. 不推荐使用

public class Car2 {
    private String brand;

    private float price;
    private String company;

    public Car2() {
        System.out.println("CarCycle'2 constructor...");
    }

//....省去get,set方法
}
public class PersonAutowire {
    private String name;
    private Address address;
    private Car2 car;

    public PersonAutowire() {
    }
//....省去get,set方法
}
public class Address {
    private String city;
    private String street;

//....省去get,set方法
}
配置文件beans-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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 这里是手工装配-->
    <!--抽象bean: bean的abstract属性为true的bean,这样的bean 不能被IOC容器实例化,只用来被继承配置
       abstract="true"
       若某一个bean的class属性没有指定,则该bean必须是一个抽象bean,也就是一个模板-->
    <bean id="address" class="Spring4_IOC.bean.Address"
          p:city="Beijing" p:street="DaZhongShi">
    </bean>

    <bean id="car2" class="Spring4_IOC.bean.Car2"
            p:brand="Audi" p:company="pachira" p:price="300000"/>

    <!--<bean id="person" class="Spring4_IOC.bean.PersonAutowire"
          p:name="Tome"  p:address-ref="address" p:car-ref="car"/>-->
    <!--将上面改为自动注入

        可以使用autowire属性指定自动装配的方式,
        byName 根据Bean的名字!!和当前bean 的setter风格的属性名进行自动装配。
        若有匹配的,则会自动装配;若无,则不会。
        因为PersonAutowire类里的setCar刚好跟上面定义的bean的id为car,所以可以自动注入进来,如将改为id="car3",则car的结果为Null
        -->
    <bean id="person" class="Spring4_IOC.bean.PersonAutowire"
          p:name="Tom" autowire="byName"/>

    <!--byType 根据bean的类型!!和当前bean 的属性的类型进行自动装配,必须唯一
               如果IOC容器中有1个以上的类型匹配的bean,则会异常。比如再添加一个Address的bean  -->
    <bean id="person2" class="Spring4_IOC.bean.PersonAutowire"
          p:name="Tom" autowire="byType"/>

</beans>
测试方法
    /**
     * 自动装配 Bean
     * byType(根据类型自动装配)
     * byName(根据名称自动装配)
     * constructor(通过构造器自动装配):不推荐使用
     */
    @Test
    public void testAutowire() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-autowire.xml");
        //测试自动装配byName
        PersonAutowire person = (PersonAutowire) ctx.getBean("person");
        System.out.println("测试自动装配byName: " + person);

        //测试自动装配byType
        PersonAutowire person2 = (PersonAutowire) ctx.getBean("person2");
        System.out.println("测试自动装配byType: " + person2);
    }
XML 配置里的 Bean 自动装配的缺点
  --•在 Bean 配置文件里设置autowire属性进行自动装配将会装配Bean的所有属性.然而,若只希望装配个别属性时,autowire属性就不够灵活了.
  --•autowire属性要么根据类型自动装配,要么根据名称自动装配,不能两者兼而有之.
  --•一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些

二、bean之间的继承与依赖

2-1.继承 Bean 配置

  --• Spring 允许继承 bean 的配置 , 被继承的 bean 称为父 b ean . 继承这个父 Bean Bean 称为子 Bean
  --• Bean 从父 Bean 中继承配置 , 包括 Bean 属性配置
  --• Bean 也可以 覆盖 从父 Bean 继承过来的配置
  --• Bean 可以作为配置模板 , 也可以作为 Bean 实例 . 若只想把父 Bean 作为模板 , 可以设置 <bean> abstract 属性为 true , 这样 Spring 将不会实例化这个 Bean
  --• 并不是 <bean> 元素里的所有属性都会被继承 . 比如 : autowire , abstract .
  --• 可以忽略父 Bean class 属性 , 让子 Bean 指定自己的类 , 而共享相同的属性配置 . 但此时 abstract 必须设为 true

2-2.依赖bean配置

  --• Spring 允许用户通过 depends-on 属性设定 Bean 前置依赖的 Bean ,前置依赖的 Bean 会在本 Bean 实例化之前创建好
  --• 如果前置依赖于多个 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

       <!--抽象bean: bean的abstract属性为true的bean,这样的bean 不能被IOC容器实例化,只用来被继承配置
   abstract="true"
   若某一个bean的class属性没有指定,则该bean必须是一个抽象bean,也就是一个模板-->
       <bean id="address" class="Spring4_IOC.bean.Address"
             p:city="Beijing" p:street="WuDaoKou">
       </bean>

       <!--    <bean id="address2" class="Spring4_IOC.bean.Address"
                 p:city="Beijing" p:street="DaZhongShi">
           </bean>-->
       <!--将上面的改为用bean 配置的继承:使用bean 的parent属性指定继承哪个bean的配置
           如果下面增加p:city="Beijing~",则获取到的bean的ity是新增的这个,而不是继承的 -->
       <bean id="address2"  p:street="DaZhongShi" parent="address">
       </bean>

       <bean id="car" class="Spring4_IOC.bean.Car2"
             p:brand="Audi" p:company="baidua" p:price="300000"/>

       <!-- 要求再配置Person时,必须有一个关联的car! 换句话说person 这个bean依赖于Car 这个bean-->
       <bean id="person" class="Spring4_IOC.bean.PersonAutowire"
             p:name="Tom"  p:address-ref="address" depends-on="car"/>
</beans>

    /**
     * bean 之间的关系:继承;依赖
     */
    @Test
    public void testRelation() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-relation.xml");
        //测试继承
        Address address = (Address) ctx.getBean("address");
        System.out.println(address);

        Address address2 = (Address) ctx.getBean("address2");
        System.out.println(address2);

        //测试依赖
        PersonAutowire person = (PersonAutowire) ctx.getBean("person");
        System.out.println("测试依赖: " + person);
    }

三、Bean 的作用域

  --• Spring , 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域 .
  --• 默认 情况下 , Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一 个实例 , 整个 IOC 容器范围内都能共享该 实例 所有 后续的 getBean () 调用和 Bean 引用都将返回这个唯一的 Bean 实例 . 该作用域被称为 singleton , 它是所有 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"
       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.xsd">

    <!--使用bean的scope属性来配置bean的作用域
        singleton:默认值,容器初始时创建bean实例,在整个容器的生命周期内只创建这一个bean.单例的
        prototype:原型的,容器初始化时不创建bean的实例,而在每次请求时都创建一个新的bean实例,并返回-->
    <bean id="car" class="Spring4_IOC.bean.Car2"
            scope="prototype">
        <property name="brand" value="Audi"/>
        <property name="price" value="300000"/>
    </bean>

</beans>
   /**
     * bean 的作用域:
     * singleton:默认值,容器初始时创建bean实例,在整个容器的生命周期内只创建这一个bean.单例的
     * prototype:原型的,容器初始化时不创建bean的实例,而在每次请求时都创建一个新的bean实例!!,
     *           并返回WEB 环境作用域(request,sessionPojo)
     */
    @Test
    public void testScope() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-scope.xml");

        Car2 car1 = (Car2) ctx.getBean("car");
        Car2 car2 = (Car2) ctx.getBean("car");
        System.out.println(car1 == car2); //默认是singleton,结果为true,如果为prototype则为false
    }

四、使用外部属性文件

  --• 配置文件里配置 Bean , 有时需要在 Bean 的配置里混入 系统部署的细节信息 ( 例如 : 文件路径 , 数据源配置信息等 ). 而这些部署细节实际上需要和 Bean 配置相分离
  --• Spring 提供了一个 PropertyPlaceholderConfigurer BeanFactory 后置处理器 , 这个处理器允许用户将 Bean 配置的部分内容外移到 属性文件 . 可以在 Bean 配置文件里使用形式为 ${ var } 的变量 , PropertyPlaceholderConfigurer 从属性文件里加载属性 , 并使用这些属性来替换变量 .
  --• Spring 还允许在属性文件中使用 ${ propName } ,以实现属性之间的相互引用。
数据配置文件db.properties
user=root
password=123456
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///test
<?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:context="http://www.springframework.org/schema/context"
       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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--导入属性文件-->
    <context:property-placeholder location="classpath:Spring4_IOC/db.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${user}"/>
        <property name="password" value="${password}"/>
        <property name="jdbcUrl" value="${jdbcUrl}"/>
        <property name="driverClass" value="${driverClass}"/>
    </bean>
   </beans>
    /**
     * 使用外部属性文件
     */
    @Test
    public void testProperties() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-properties.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
    }




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值