Spring框架中 Bean对象属性值的注入

时间:2022-06-16
本文章向大家介绍Spring框架中 Bean对象属性值的注入,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在Spring框架中,主要有两种常用的 Bean对象属性注入值方式:

1、set注入:是通过调用对象的setter方法为Bean对象属性赋值

2、构造注入:是通过Bean对象的构造函数为Bean对象属性注入值

注意:如果一个Bean对象同时存在set注入和构造注入两种方法,Spring在为Bean对象属性赋值时,会先使用set注入方式为属性赋值,再使用构造注入为Bean对象属性赋值。

在 Spring 中为 Bean 对象注入值分为三种类型:

1、直接量值的注入:

Spring 直接量值的注入指的是通过Spring IOC为对象的8种基本类型封装类以及String类型的属性注入值。

// 例如定义一个属性类型为基本类型和String的对象
public class ConnectionPool {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private int maxIdle;
    private int maxActive;
   
 public String getUrl() {
       return url;
 }
 public void setUrl(String url) {
       this.url = url;
 }
 // .......
}

然后直接使用set注入为bean进行直接量值的注入,即直接在value的等号后直接填写相对应的值就行:

<!-- 直接量值得注入方式 -->
<bean id="dataSource" class="com.jt.common.utils.ConnectionPool">
     <property name="driverClassName" value="com.jdbc.mysql.Driver"/>
     <property name="url" value="jdbc:mysql:///test"/>
     <property name="username" value="root"/>
     <property name="password" value="root"/>
</bean>

为了便于后期维护,不将数据写死在配置文件里,可以将配置信息提取出来,以key=value的形式保存到properties文件中,然后通过Spring表达式 #{id.key} 的方式提取数据;

比如在类路径下定义一个configs.properties文件,内容格式如下:

jdbcDriver= com.mysql.jdbc.Driver
jdbcUrl= jdbc:mysql:///test
jdbcUser= root
jdbcPassword=root

然后在Spring配置文件中先引入configs.properties文件:

<util:properties id="cfg" location="classpath:configs.properties"/>

再修改Bean配置文件,使用spring表达式取值:

 <bean id="dataSource" class="com.jt.common.utils.ConnectionPool">
       <property name="driverClassName" value="#{cfg.jdbcDriver}"/>
       <property name="url" value="#{cfg.jdbcUrl}"/>
       <property name="username" value="#{cfg.jdbcUser}"/>
       <property name="password" value="#{cfg.jdbcPassword}"/>
 </bean>

注意:# 为spring表达式特殊标记, { } 为表达式内容, cfg 为util:properties 标签中定义的id

jdbcUser、jdbcPassword为配置文件等号左边的key

2、集合对象值的注入:

在spring中为集合对象注入值时,主要是通过使用配置文件中的标签对属性值进行封装,spring在创建对象时会根据对应的标签生成相对应的对象,来进行属性值的注入

public class Configuration {
  private List<String> list;
  private Map<String,Object> map;
  private Properties properties;
  
  public void setList(List<String> list) {
      this.list = list;
  }
  public void setMap(Map<String, Object> map) {
      this.map = map;
  }
  public void setProperties(Properties properties) {
      this.properties = properties;
  }
 ...
}

为Configuration对象中List、Map、Properties属性赋值的方式如下:

<bean id="config" class="beans.Configuration">
    <property name="list">
      <list>
         <value>A</value>
         <value>B</value>
      </list>
    </property>
    <property name="map">
       <map>
          <entry key="k1" value="100" />
          <entry key="k2" value="300" />
       </map>
    </property>
    <property name="properties">
       <props>
          <prop key="username">root</prop>
          <prop key="password">123456</prop>
       </props>
    </property>
</bean>

3、依赖对象值的注入

实际项目会存在很多个Bean对象,这些对象之间会存在一定依赖关系,当某个Bean对象依赖于其它Bean对象,可以通过spring按照一定的规则(例如按类型或者按名字),进行依赖查找然后进行值的注入。

例如:现有一生产者对象(Producer),此对象关联一容器(Container)对象,然后可以通过容器对象存储相关数据。

设计容器类对象:基于FIFO(先进先出算法)设计一个容器对象,底层实现为数组

public class Container {
  /**存储元素*/
  private Object[] array;
  /**记录有效元素个数*/
  private int size;
  
  public Container() {
     this(10);//默认为10
  }
  public Container(int cap){//cap为初始容量
     array=new Object[cap];
  }
  
  /**向容器放数据(没有容量限制,容器满了要扩容)*/
  public void add(Object obj){   
    //放到size位置
    //1.判定容器是否已满,满了则扩容
    if(size==array.length){
        array=Arrays.copyOf(array,   //original (原数组)
                  2*array.length);   //newLength(新长度)
    }
    //2.放数据到容器
    array[size]=obj;
    
   //3.有效元素个数加1
    size++;
  }
  
  /**从容器取数据(按照FIFO规则获取数据)*/
  public Object remove(){
    //永远取0位置的元素
    //1.获取第0个位置的数据
    if(size==0)return null;
        Object data=array[0];
    //2.移动元素(元素的拷贝)
    System.arraycopy(
            array,        //src原数组
            1,            //srcPos从原数组的哪个位置开始拷贝
            array,        //dest目标数组
            0,            //destPos从目标数组的哪个位置开始放
            size-1);      //length拷贝多少个
    //3.有效元素个数减一
      size--;
    //4.size位置的设置为null
      array[size]=null;
      return data;
    }
}

生产者对象类的设计:

/**生产者对象(负责向容器放数据)*/
public class Producer {
    //IOC(工厂,容器)
    /**生产者关联一个容器对象(目的是要向此容器放数据)*/
    private Container container;
    
    public void setContainer(Container container) {
         this.container = container;
     }
     
    public Container getContainer() {
         return container;
     }
}

消费者对象设计:

/**生产者对象(负责向容器放数据)*/
public class Consumer{
 //IOC(工厂,容器)
 /**生产者关联一个容器对象(目的是要向此容器放数据)*/
 private Container container;
 
 public Consumer(Container container) {
     this.container = container;
 }
 public Container getContainer() {
     return container;
 }
}

类的基本配置:

<!-- 配置容器对象:容量初始大小为16 -->
<bean id="container" class="com.jt.common.mq.Container">
    <constructor-arg value="16"/>
</bean>

<!-- 配置生产者对象 -->
<bean id="producer" class="com.jt.common.mq.Producer">
    <property name="Container" ref="container"/>
</bean>

<!-- 配置消费者对象 -->
<bean id="consumer" class="com.jt.common.mq.Consumer">
     <property name="Container" ref="container"/>
</bean>