2.bean的命名和实例化依赖注入方式

Posted yuanGrowing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.bean的命名和实例化依赖注入方式相关的知识,希望对你有一定的参考价值。

2.1bean的命名

2.1.1 name属性
bean有一个id属性和一个name属性,其中id是唯一的,但是name可以是多个。比如这样就可以定义一个多name的bean
<bean id="userdao" class="com.example.maven.UserDao" name="userdao1,userdao2">
2.1.2 alias 标签
alias可以用来给已存在的bean取别名,其格式如下:
<aliasname="fromName"alias="toName"/>
如果已存在一个叫userdao的bean,通过如下方式可以将其另取名为userdaox
<alias name="userdao" alias="userdaox"></alias>

2.2bean的实例化
bean的实例化有三种方式,构造器、静态工厂方法、实例工厂方法

2.2.1 instantiation with a constructor
   这是最简单的构造方式,当一个bean以如下方式进行定义时,ioc容器就会使用它自己的构造函数进行实例化。
<bean id="exampleBean"class="examples.ExampleBean"/>
 2.2.2 instantiation with a static factory method             
 当bean的定义中指定了factory-method属性时,ioc容器会选择factory-method制定的函数进行实例化。

 如下例子中,ioc会使用UserDao中的getUserDao方法进行实例化,不过这个方法必须是静态方法。
<bean id="userdaofactory" class="com.example.maven.UserDao" factory-method="getUserDao"></bean>
public class UserDao
    public static UserDao getUserDao()
       return new UserDao();
    
    2.2.3 instantiation with a instance factory method
       类似于工厂模式,在spring中也可以为某个类做一个工厂类,来管理其实例化。如下例子中,ioc容器会调用UserDaoFactory.getInstance()方法来实例化一个UserDao类。
<bean id="userdaofactory" class="com.example.maven.UserDaoFactory"></bean>
<bean id=userdao factory-bean="userdaofactory" factory-method="getInstance"></bean>
public class UserDaoFactory 
    public static UserDao getInstance()
            System.out.println("do userdaofactory");
        return new UserDao();
    

2.3 依赖注入的两种方式
依赖注入是spring的重点,有两种方式,构造器注入和get/set方法注入

    2.3.1 构造器注入
        简单的说,依赖就是类中的成员变量,实例的同时让这些成员变量有自己的值就是依赖注入,显然,我们在构造函数中将这些成员变量以参
  数的形式进行初始化即可完成依赖注入。
        例子:假设有一个UserBean定义如下,
public class UserDao 
private UserBean user ;
private int id;
private  String name ;
   public UserDao(UserBean user, int id, String name)
this.user = user ;
    this.id=id;
    this.name=name;
    
//get/set方法
在配置文件中,我们可以通过三种方式完成多参数的依赖注入。
        第一种,和构造函数中的顺序一样,将参数一个个注入            
<constructor-argref="userbean"></constructor-arg>
<constructor-argvalue="1"></constructor-arg>
<constructor-arg value="test"></constructor-arg>
        第二种,利用index进行指定,index从0开始
<constructor-arg index="0" ref="userbean"></constructor-arg>
<constructor-arg index="1" value="1"></constructor-arg>
<constructor-arg index="2" value="test"></constructor-arg>
        第三种,利用name进行指定
<constructor-arg name="id" value="123"></constructor-arg>
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="user" ref="userbean"></constructor-arg>
        从上面的配置中,也可以看出如果参数是一个类,那么就用ref属性,如果是一般的数据类型,就用value。
        完整配置如下:
<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">
<bean id="userbean" class="com.example.maven.UserBean"></bean>
<bean id="userdao" class="com.example.maven.UserDao">

<constructor-arg ref="userbean"></constructor-arg>
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="test"></constructor-arg>

<!--<constructor-arg index="0" ref="userbean"></constructor-arg>-->
    <!--<constructor-arg index="1" value="1"></constructor-arg>-->
    <!--<constructor-arg index="2" value="test"></constructor-arg>-->

    <!--<constructor-arg name="id" value="123"></constructor-arg>-->
    <!--<constructor-arg name="name" value="test"></constructor-arg>-->
    <!--<constructor-arg name="user" ref="userbean"></constructor-arg>-->

</bean>
</beans>
    2.3.2 get/set方法注入
    和上面的例子类似,假设有一个UserDao类,它只有一个默认的无参构造函数
public class UserDao 
private UserBean user ;
private int id;
private  String name ;
// get/set方法
    那么,我们可以通过get/set方法进行依赖注入。这里就用到了property标签,标签中name属性指的就是bean中成员变量的名称。
<property name="id" value="1"></property>
<property name="name" value="test"></property>
<property name="user" ref="userbean"></property>
    在使用get/set进行依赖注入的时候,ioc容器应该是先实例化出所有的类,然后再进行依赖注入的。为了验证这个想法,我使用两个相互依赖的类,UserDao和UserBean,
public class UserDao 
    private UserBean user ;
    private int id;
    private  String name ;

UserDao()
    System.out.println("create userdao");

// get/set方法
public void setUser(UserBean user) 
    System.out.println("do setuser");
    this.user = user;


public class UserBean 
    private String name ;
    private  UserDao userDao;
UserBean()
    System.out.println("create userbean");


// get/set方法
public void setUserDao(UserDao userDao) 
    System.out.println("do setuserdao");
    this.userDao = userDao;


    配置文件如下:
<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">
    <bean id="userbean" class="com.example.maven.UserBean">
        <property name="userDao" ref="userdao"></property>
        <property name="name" value="test"></property>
    </bean>
    <bean id="userdao" class="com.example.maven.UserDao">

        <property name="id" value="1"></property>
        <property name="name" value="test"></property>
        <property name="user" ref="userbean"></property>
    </bean>
</beans>
    测试函数:
ApplicationContext app = new ClassPathXmlApplicationContext("spring-main.xml");
      UserDao userDao = (UserDao) app.getBean("userdao");
      UserBean userBean = (UserBean) app.getBean("userbean");
    结果如下:
create userbean
create userdao
do setuser
do setuserdao
    从结果可以看出,容器的确是先构造bean再进行依赖注入的。


2.3.3 多种集合的依赖注入
    spring提供了四种集合的依赖注入list、map、property和set(这里的集合是java5之前的,也就是list里面不需要定义具体类型的那种;不过即使是java5以后的带具体类型的集合,用法也差不多),分别使用标签<list/>, <map/>, and <props/> 和<set/>。在spring和hibernate整合的时候就用到了prop的依赖注入。
    具体使用看下面的例子:
public class UserDao 
    private List list;
    private Set set;
    private Properties properties;
    private Map map;
    //get/set方法
    配置文件
<bean id="userdao" class="com.example.maven.UserDao" name="userdao1,userdao2">
    <property name="list">
        <list>
            <value>list data1</value>
            <value>list data2</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>set data1</value>
            <value>set data2</value>
        </set>
    </property>
    <property name="properties">
        <props>
            <prop key="data1">prop data1</prop>
            <prop key="data2">prop data2</prop>
        </props>
    </property>
    <property name="map">
        <map>
            <entry key="data1" value="map data1"></entry>
            <entry key="data2" value="map data2"></entry>
        </map>
    </property>
</bean>
   测试代码如下:
ApplicationContext app = new ClassPathXmlApplicationContext("spring-main.xml");
      UserDao userDao = (UserDao) app.getBean("userdao3");
      List list = userDao.getList();
      for (int i = 0; i < list.size(); i++) 
          System.out.println(list.get(i));
      
      Iterator iterator = userDao.getSet().iterator();
      while (iterator.hasNext())
          System.out.println(iterator.next());
      
      Properties properties = userDao.getProperties();
      System.out.println(properties.getProperty("data1"));
      Map map = userDao.getMap();
      System.out.println(map.get("data1"));
    结果:
list data1
list data2
set data1
set data2
prop data1
map data1

以上是关于2.bean的命名和实例化依赖注入方式的主要内容,如果未能解决你的问题,请参考以下文章

SPRING01_概述配置文件bean实例化依赖注入的方式依赖注入的数据类型分模块开发API使用

框架----Spring中依赖注入

Spring -- Spring配置文件详解(Bean实例化的三种方式IoC(控制反转) 与 DI(依赖注入)依赖注入详解)

spring 注入 和 实例化的差别(别说没区别)

关于Spring依赖注入的问题

依赖注入之setter注入---只需修改配置,电脑就可以安装不同的打印机;读取properties配置文件并创建实例;实现不采用new的方式直接实例化对象