Spring知识整理(二)Spring之Bean的基本配置

                          

1.(OC & DI概述)

 

IOC(Inversion of Control):其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式

DI(Dependency Injection)IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接

                 

             

              

2.(Bean)

Bean是Spring的控制反转,利用反射为我们创建实例的基础配置好Bean尤其重要

 

(•在Spring的配置文件 xml 文件中通过 bean 节点来配置 bean)

<!-- 配置一个 bean -->
<!--class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求bean中必须有无参构造函数-->
<!--id:创建完成bean之后,通过id来获取bean,id唯一-->
<bean id="helloWorld" class="HelloWorld">
   <!-- 为属性赋值 -->
   <!--property中的name所对应的属性需要在Class所指定的类中具有set方法-->
   <property name="name" value="Spring"></property>
</bean>

Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.

Spring 提供了两种类型的 IOC 容器实现.

BeanFactory: IOC 容器的基本实现.

ApplicationContext: 提供了更多的高级特性. BeanFactory的子接口.

BeanFactorySpring 框架的基础设施,面向 Spring 本身;ApplicationContext面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext而非底层的 BeanFactory

无论使用何种方式, 配置文件时相同的.

ApplicationContext的主要实现类:

ClassPathXmlApplicationContext类路径下加载配置文件

FileSystemXmlApplicationContext: 从文件系统中加载配置文件

ConfigurableApplicationContext扩展于 ApplicationContext,新增加两个主要方法:refresh() close(), 让 ApplicationContext具有启动、刷新和关闭上下文的能力

ApplicationContext在初始化上下文时就实例化所有单例的 Bean

WebApplicationContext是专门为 WEB 应用而准备的,它允许从相对于WEB 根目录的路径中完成初始化工作

                             

//        原始方法
//        HelloWorld helloWorld =new HelloWorld();
//        helloWorld.setName("spring");

(使用Spring之后,对象的创建交给Spring的IOC容器创建)

//          1.创建Spring的IOC容器对象
          ApplicationContext applicationContext =new ClassPathXmlApplicationContext("classpath:spring/applicationContex.xml");
//          2.从IOC容器中获取Bean实例
          HelloWorld helloWorld = (HelloWorld) applicationContext.getBean("helloWorld");
//           3.调用方法
          helloWorld.hello();

 

 

2.1(依赖注入的方式)

 

Spring 支持 3 种依赖注入的方式

属性注入

(属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象

属性注入使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值

属性注入是实际应用中最常用的注入方式

)

<!-- 配置一个 bean -->
<!--class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求bean中必须有无参构造函数-->
<!--id:创建完成bean之后,通过id来获取bean,id唯一-->
<bean id="helloWorld" class="HelloWorld">
   <!-- 为属性赋值 -->
   <!--property中的name所对应的属性需要在Class所指定的类中具有set方法-->
   <property name="name" value="Spring"></property>
</bean>

 

构造器注入(

通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。

构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性

package com.spring.beans;

/**
 * Created by Administrator on 2018/3/31.
 */
public class CarBean {
    private  String name;
    private  int price;

    public CarBean(String name, int price) {
        this.name = name;
        this.price = price;
    }
    public  CarBean(){

    }

    @Override
    public String toString() {
        return "CarBean{" +
                "name='" + name + '\'' +
                ", price='" + price + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

 

按索引匹配入参:(可以单独使用value子标签,也可以使用value属性来赋值)

<bean id="car" class="com.spring.beans.CarBean">
   <constructor-arg value="宝马" index="0"></constructor-arg>
   <constructor-arg index="1">
      <value>300000</value>
   </constructor-arg>
</bean>

按类型匹配入参:

<bean id="car" class="com.spring.beans.CarBean">
   <constructor-arg value="宝马" type="java.lang.String"></constructor-arg>
   <constructor-arg type="int">
      <value>300000</value>
   </constructor-arg>
</bean>

字面值:可用字符串表示的值,可以通过<value> 元素标签或 value 属性进行注入。

基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式

若字面值中包含特殊字符,可以使用 <![CDATA[]]> 把字面值包裹起来。

<!--通过构造方法来配置bean的属性-->
<!--index:标识构造方法中第几个参数-->
<!--type:构造器中参数的类型-->
<!--index与type可以混合使用,也可以单独使用一个,type是为了解决重载的构造函数-->
<!--属性值可以使用<value>标签,也可以使用value属性-->
   <!--如果字面值包含特殊的字符例如<北京宝马!>可以使用<![CDATA[<北京宝马!>]]>将其包裹起来-->

 

工厂方法注入(很少使用,不推荐)

 

2.2(引用其它 Bean)

 

<bean id="person" class="com.spring.beans.PersonBean">
   <property name="name" value="小贤"></property>
   <property name="car" ref="car"></property>
   <!--=====================================也可以使用内部bean,不能被外部引用只能在内部使用============================-->
   <!--<property name="car" >-->
      <!--<bean class="com.spring.beans.CarBean">-->
         <!--<constructor-arg value="宝马" index="0" type="java.lang.String"></constructor-arg>-->
         <!--<constructor-arg index="1" type="int">-->
            <!--<value>500000</value>-->
         <!--</constructor-arg>-->
      <!--</bean>-->
   <!--</property>-->
</bean>

2.3(集合属性)

 

Spring可以通过一组内置的 xml 标签(例如: <list>, <set> <map>) 来配置集合属性.

配置 java.util.List类型的属性, 需要指定 <list> 标签, 在标签里包含一些元素. 这些标签可以通过 <value>指定简单的常量值, 通过 <ref>指定对其他 Bean 的引用. 通过<bean>指定内置 Bean 定义. 通过 <null/> 指定空元素. 甚至可以内嵌其他集合.

数组的定义和 List 一样, 都使用 <list>

配置 java.util.Set需要使用 <set>标签, 定义元素的方法与 List 一样.

package com.spring.beans;

import java.util.List;

/**
 * Created by Administrator on 2018/3/31.
 */
public class CollectionBean {
    //集合
    private List<CarBean> cars;

    public List<CarBean> getCars() {
        return cars;
    }

    public void setCars(List<CarBean> cars) {
        this.cars = cars;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "cars=" + cars +
                '}';
    }
}
<!--=====================================配置List集合属性============================-->
<bean id="collection" class="com.spring.beans.CollectionBean">
   <property name="cars" ref="carlist">
      <!--使用list标签来配置-->
      <!--<list>-->
         <!--<ref bean="car"></ref>-->
         <!--<ref bean="car"></ref>-->
         <!--<ref bean="car"></ref>-->
         <!--<ref bean="car"></ref>-->
      <!--</list>-->
   </property>
</bean>
<!--=====================================可以将list,map,properties等单独定义,方便复用============================-->
<util:list id="carlist">
   <ref bean="car"></ref>
   <ref bean="car"></ref>
   <ref bean="car"></ref>
</util:list>

Java.util.Map通过 <map>标签定义,<map> 标签里可以使用多个 <entry>作为子标签. 每个条目包含一个键和一个值.

必须在 <key>标签里定义键

因为键和值的类型没有限制, 所以可以自由地为它们指定 <value>, <ref>, <bean> <null>元素.

可以将 Map 的键和值作为 <entry>的属性定义: 简单常量使用 key value 来定义; Bean 引用通过 key-ref value-ref属性定义

使用 <props>定义 java.util.Properties, 该标签使用多个 <prop>作为子标签. 每个 <prop>标签必须定义 key属性

package com.spring.beans;

import java.util.Map;

/**
 * Created by Administrator on 2018/3/31.
 */
public class MapBean {
    Map<String,CarBean> map;

    public Map<String, CarBean> getMap() {
        return map;
    }

    public void setMap(Map<String, CarBean> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "MapBean{" +
                "map=" + map +
                '}';
    }
}
<!--=====================================配置Map属性值============================-->
<bean id="map" class="com.spring.beans.MapBean">
   <property name="map">
      <map>
         <entry key="A" value-ref="car"></entry>
         <entry key="B" value-ref="car"></entry>
         <entry key="C" value-ref="car"></entry>
      </map>
   </property>
</bean>

使用 <props>定义 java.util.Properties, 该标签使用多个 <prop>作为子标签. 每个 <prop>标签必须定义 key属性

package com.spring.beans;

import java.util.Properties;

/**
 * Created by Administrator on 2018/3/31.
 */
public class PropertiesBean {
    private Properties properties;

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "PropertiesBean{" +
                "properties=" + properties +
                '}';
    }
}

 

<!--=====================================配置properties属性============================-->
<bean id="properties" class="com.spring.beans.PropertiesBean">
   <property name="properties">
      <props>
         <prop key="user">root</prop>
         <prop key="password">root</prop>
         <prop key="driver">root</prop>
         <prop key="url">root</prop>
      </props>
   </property>
</bean>

2.4(使用 p 命名空间)

 

<!--使用p命名空间-->
   <bean id="p-helloWorld" class="HelloWorld" p:name="p-spring">
</bean>

为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。

Spring 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性。

使用 p 命名空间后,基于 XML 的配置方式将进一步简化

 

2.5(XML 配置里的 Bean 自动装配)

 

Spring IOC 容器可以自动装配 Bean. 需要做的仅仅是<bean> autowire属性里指定自动装配的模式

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

byName(根据名称自动装配): 必须将目标 Bean 的名称和属性名设置的完全相同.

constructor(通过构造器自动装配): Bean 中存在多个构造器时, 此种自动装配方式将会很复杂. 不推荐使用

package com.spring.beans;

/**
 * Created by Administrator on 2018/3/31.
 */
public class AutowireBean {
    //自动装配
    private String name;
    private  CarBean car;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public CarBean getCar() {
        return car;
    }

    public void setCar(CarBean car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "AutowireBean{" +
                "name='" + name + '\'' +
                ", car=" + car +
                '}';
    }
}
<?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-->
   <bean id="car" class="com.spring.beans.CarBean">
      <property name="name" value="保时捷"></property>
      <property name="price" value="100000000"></property>
   </bean>
   <!--自动装配-->
   <!--byName根据bean的id和当前bean的set方法属性进行自动匹配,若有匹配的则匹配,否则不匹配-->
   <!--byType:根据bean的类型和bean的属性的类型进行自动装配(名字对不上,类型对的上也可以,但是,如果IOC容器有两个以上类型一样的,byType就无法装配了)-->
   <bean id="autowire" class="com.spring.beans.AutowireBean"  p:name="小贤" autowire="byName"></bean>
   </beans>

Bean 配置文件里设置 autowire属性进行自动装配将会装配 Bean 的所有属性. 然而, 若只希望装配个别属性时, autowire属性就不够灵活了.

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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值