你的位置:首页 > 软件开发 > Java > Spring IOC容器

Spring IOC容器

发布时间:2015-06-17 12:00:22
实例化Spring容器示例 利用Spring容器创建JavaBean对象 如何控制Bean实例化 利用Spring实现bean属性setter方式注入 利用构造器参数实现依赖属性的注入 利用 ...

Spring IOC容器

 

 

1 实例化Spring容器示例

1.1 问题

使用ApplicationContext的方式实例化Spring容器。

1.2 方案

使用ApplicationContext的方式实例化Spring容器的核心代码如下:

  String conf = "applicationContext.;  ApplicationContext ac =       new ClassPath

applicationContext.

<?    ="http://www.springframework.org/schema/context"      ="http://www.springframework.org/schema/jee"     ="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd      http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"></beans>

这里定义了两个bean, 其中一个bean calendarObj3是用于创建 dateObj 对象的实例工厂.

另外一个bean标记中id属性dateObj用于定义bean名字, 是程序代码中获得Spring管理bean对象的标识, 这个名字不能重复, factory-bean属性用于指定创建对象的工厂对象calendarObj3, 前面定义的一个bean, factory-method属性用于指定创建对象的工厂方法getTime, Spring会自动的调用工厂类Calendar静态工厂方法getInstance创建bean对象实例.

2.3 步骤

步骤一:配置 applicationContext.

代码如下所示:

<!-- 1. 用构造器来实例化的方式的配置代码如下: -->  <bean id="calendarObj1" class="java.util.GregorianCalendar"></bean>  <!-- 2. 使用静态工厂方法实例化的方式的配置代码如下: -->  <bean id="calendarObj2" class="java.util.Calendar"    factory-method="getInstance">  </bean>  <!-- 3. 使用实例工厂方法实例化的方式的配置代码如下: -->  <bean id="calendarObj3" class="java.util.GregorianCalendar"></bean>  <bean id="dateObj" factory-bean="calendarObj3"    factory-method="getTime">  </bean>

步骤二:在TestCase类中增加测试方法testCreateBeanObject,测试Spring创建对象的结果

先创建Spring容器对象, 再调用getBean方法获得Spring创建的对象实例,并且利用输出语句测试对象是否存在. 这个代码中要注意: getBean方法的参数必须是上一个步骤中定义的bean标记上的id属性的值, 否则会出现运行异常.

代码如下所示:

/** 测试Spring支持的多种JavaBean对象创建方式 */  @Test  public void testCreateBeanObject() {    // 实例化Spring容器示例    String conf = "applicationContext.;    ApplicationContext ac = new ClassPath// 1. 用构造器来实例化的方式。    // 利用Spring调用构造器 GregorianCalendar 创建 Calendar实例.    // Calendar cal1 = (Calendar)ac.getBean("calendarObj1"); //方式1    Calendar cal1 = ac.getBean("calendarObj1", Calendar.class); // 方式2    System.out.println("cal1:" + cal1);    // 2. 使用静态工厂方法实例化的方式。    // 利用Spring调用 Calendar 的静态工厂方法getInstance() 创建 Calendar实例.    Calendar cal2 = ac.getBean("calendarObj2", Calendar.class);    System.out.println("cal2:" + cal2);    // 3. 使用实例工厂方法实例化的方式。    // 利用Spring创建 GregorianCalendar 对象作为工厂, 调用getTime()方法创建Date类型对象实例.    Date date = ac.getBean("dateObj", Date.class);    System.out.println("date:" + date);  }

步骤三:运行测试方法测试bean实例化

控制台输出结果如下所示:

cal1:java.util.GregorianCalendar[time=1434446926808,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=5,WEEK_OF_YEAR=25,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=167,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=28,SECOND=46,MILLISECOND=808,ZONE_OFFSET=28800000,DST_OFFSET=0]cal2:java.util.GregorianCalendar[time=1434446926837,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=5,WEEK_OF_YEAR=25,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=167,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=28,SECOND=46,MILLISECOND=837,ZONE_OFFSET=28800000,DST_OFFSET=0]date:Tue Jun 16 17:28:46 CST 2015

 

上述运行结果可以看得出在软件运行期间ExampleBean的构造器只被调用过一次, 创建过一个对象,两次获得引用变量bean1, bean2,通过比较操作符“ ==” 进行比较的输出结果为true, 说明是引用了同一个对象, 也就说明Spring容器创建Bean对象是唯一实例, 是单例对象。

5. 修改applicationContext. 

 

这个结果说明调用了2次ExampleBean类的构造方法创建了两个Bean对象,比较结果是false表示bean1和bean2引用了这两个不同的对象, 这样创建bean就不再是单例模式了。

步骤二:Bean对象的初始化和销毁

1. 修改ExampleBean类,加入方法init和方法destroy,代码如下所示:

package com.souvc.dao;public class ExampleBean {  public ExampleBean() {    System.out.println("实例化ExampleBean");  }  public void execute() {    System.out.println("执行ExampleBean处理");  }  public void init() {    System.out.println("初始化ExampleBean对象");  }  public void destroy() {    System.out.println("销毁ExampleBean对象");  }}

2. 修改applicationContext.

<!-- scope="prototype" 模式 -->  <bean id="exampleBean" class="com.souvc.dao.ExampleBean"    scope="prototype" init-method="init">  </bean>

 

 

 

2. 修改applicationContext.

<!-- scope="prototype" 模式 -->  <bean id="exampleBean" class="com.souvc.dao.ExampleBean"    scope="singleton" init-method="init" destroy-method="destroy"    lazy-init="true" depends-on="exampleBean1">  </bean>  <!-- scope="prototype" 模式 -->  <bean id="exampleBean1" class="com.souvc.dao.ExampleBean1"    lazy-init="true">  </bean>

利用Spring实现JDBCDataSource对象的创建, 再使用setter注入的方式将数据库连接参数注入给JDBCDataSource。这样就可以正常的调用getConnection()方法获得数据库连接了.

4.2 方案

利用Spring配置文件applicationContext.

applicationContext. 

4.3 步骤

步骤一:新建工程,导入jar

新建名为SouvcSpringIoC的web工程,在该工程导入如下面所示的6个jar包, 包括Spring API 和 Oracle JDBC Driver或者mysql JDBC DRIVER。

 

commons-logging.jar

步骤三:新建applicationContext.

在配置文件中声明JDBCDataSource实例的bean ID为"dataSource", 该文件的核心代码如图-29所示:

<!-- setter注入 mysql -->  <bean id="dataSource" class="com.souvc.dao.JDBCDataSource">    <property name="driver" value="com.mysql.jdbc.Driver"></property>    <property name="url" value="jdbc:mysql://localhost:3306/test">    </property>    <property name="user" value="root"></property>    <property name="pwd" value="123456"></property>  </bean>

如果能够输出如上结果, 说明能够成功的获取Oracle JDBC 连接, 也就说明Spring成功的调用Setter方法注入了数据库连接参数。

4.4 完整代码

JDBCDataSource类的完整代码如下所示:

package com.souvc.dao;import java.io.Serializable;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class JDBCDataSource implements Serializable {  private String driver;  private String url;  private String user;  private String pwd;  public String getDriver() {    return driver;  }  public void setDriver(String driver) {    try {      // 注册数据库驱动      Class.forName(driver);      this.driver = driver;    } catch (Exception e) {      throw new RuntimeException(e);    }  }  public String getUrl() {    return url;  }  public void setUrl(String url) {    this.url = url;  }  public String getUser() {    return user;  }  public void setUser(String user) {    this.user = user;  }  public String getPwd() {    return pwd;  }  public void setPwd(String pwd) {    this.pwd = pwd;  }  public Connection getConnection() throws SQLException {    Connection conn = DriverManager.getConnection(url, user, pwd);    return conn;  }  public void close(Connection conn) {    if (conn != null) {      try {        conn.close();      } catch (SQLException e) {        e.printStackTrace();      }    }  }}

TestCase类的完整代码如下所示:

package com.souvc.test;import java.sql.Connection;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathimport com.souvc.dao.JDBCDataSource;public class TestCase {  /** Setter 注入测试 */  @Test  public void testJDBCDataSource() throws Exception {    String conf = "applicationContext.;    ApplicationContext ac = new ClassPath= ac.getBean("dataSource", JDBCDataSource.class);    Connection conn = ds.getConnection();    System.out.println(conn);  }}

applicationContext.

<?  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/context"  ="http://www.springframework.org/schema/jdbc"  ="http://www.springframework.org/schema/jee"  ="http://www.springframework.org/schema/tx"  ="http://www.springframework.org/schema/data/jpa"  xsi:schemaLocation="      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd      http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">  <!-- setter注入 oracle     <bean id="dataSource" class="com.souvc.dao.JDBCDataSource">    <property name="driver" value="oracle.jdbc.OracleDriver"></property>    <property name="url"    value="jdbc:oracle:thin:@localhost:1521:ora1">    </property>    <property name="user" value="root"></property>    <property name="pwd" value="123456"></property>    </bean>  -->  <!-- setter注入 mysql -->  <bean id="dataSource" class="com.souvc.dao.JDBCDataSource">    <property name="driver" value="com.mysql.jdbc.Driver"></property>    <property name="url" value="jdbc:mysql://localhost:3306/cnblogs">    </property>    <property name="user" value="root"></property>    <property name="pwd" value="123456"></property>  </bean></beans>

5.3 步骤

步骤一:新建业务实体类: User类

User类代表软件中的用户实例类型, 用户对象信息存储在Oracle数据库中.User类代码如下所示:

package com.souvc.entity;import java.io.Serializable;  public class User implements Serializable {    private int id;    private String name;    private String pwd;    private String phone;        public User() {    }    public User(int id, String name, String pwd, String phone) {      this.id = id;      this.name = name;      this.pwd = pwd;      this.phone = phone;    }    public User(String name, String pwd, String phone) {      super();      this.name = name;      this.pwd = pwd;      this.phone = phone;    }    public int getId() {      return id;    }    public void setId(int id) {      this.id = id;    }    public String getName() {      return name;    }    public void setName(String name) {      this.name = name;    }    public String getPwd() {      return pwd;    }    public void setPwd(String pwd) {      this.pwd = pwd;    }    public String getPhone() {      return phone;    }    public void setPhone(String phone) {      this.phone = phone;    }    @Override    public int hashCode() {      return id;    }    @Override    public boolean equals(Object obj) {      if (this == obj)        return true;      if (obj == null)        return false;      if (obj instanceof User) {        User o = (User) obj;        return this.id == o.id;      }      return true;    }        @Override    public String toString() {      return id+","+name+","+pwd+","+phone;    }  }

步骤二:创建Oracle数据库初始化SQL脚本, 并且执行

创建Oracle数据库的初始化SQL脚本, 在数据库中创建Users表, 并且存入实例数据用于测试需要, 在Oracle上执行这个SQL脚本. Oracle初始化SQL脚本参考如下:

 

  -- 创建用户表  CREATE TABLE tb_users  (   ID NUMBER(7, 0) ,    NAME VARCHAR2(50) ,    PWD VARCHAR2(50),    PHONE VARCHAR2(50) ,   PRIMARY KEY (id),   -- 登录用户名唯一约束   constraint name_unique unique(name)  );  -- 用户ID生成序列  CREATE SEQUENCE SEQ_USERS;  -- 向数据库插入模拟数据  insert into tb_users(id, name, pwd, phone) values (SEQ_USERS.nextval, 'Tom', '123', '110');  insert into tb_users(id, name, pwd, phone) values (SEQ_USERS.nextval, 'Jerry', 'abc', '119');  insert into tb_users(id, name, pwd, phone) values (SEQ_USERS.nextval, 'Andy', '456', '112');

步骤四:创建OracleUserDAO类,实现UserDAO接口定义的功能

创建OracleUserDAO类, 实现UserDAO接口的findByName方法, 该方法用户从数据库中根据唯一的用户名查询用户对象, 如果没有查询到对象返回null. 这个方法的实现必须依赖于JDBCDataSource属性, 需要利用JDBCDataSource获得数据库连接, 进行数据查询得到用户数据. 参考代码如下:

package com.souvc.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.souvc.entity.User;public class OracleUserDAO implements UserDAO {  private JDBCDataSource dataSource;  /** 创建 OracleUserDAO 对象必须依赖于JDBCDataSource实例 */  public OracleUserDAO(JDBCDataSource dataSource) {    this.dataSource = dataSource;  }  /** 根据唯一用户名查询系统用户, 如果没有找到用户信息返回null */  public User findByName(String name) {    System.out.println("利用JDBC技术查找User信息");    String sql = "select id, name, pwd, phone from USERS where name=?";    Connection conn = null;    try {      conn = dataSource.getConnection();      PreparedStatement ps = conn.prepareStatement(sql);      ps.setString(1, name);      ResultSet rs = ps.executeQuery();      User user = null;      while (rs.next()) {        user = new User();        user.setId(rs.getInt("id"));        user.setName(rs.getString("name"));        user.setPwd(rs.getString("pwd"));        user.setPhone(rs.getString("phone"));      }      rs.close();      ps.close();      return user;    } catch (SQLException e) {      e.printStackTrace();      throw new RuntimeException(e);    } finally {      dataSource.close(conn);    }  }}

步骤五:配置Spring添加OracleUserDAO的bean定义

在applicationContext.

<!-- 构造器注入 -->  <bean id="userDAO" class="com.souvc.dao.MysqlUserDAO">    <!-- 利用构造器参数注入bean的属性 -->    <constructor-arg name="dataSource" ref="dataSource" />  </bean>

从输出结果可以看出调用到了OracleUserDAO对象的findByName方法, 说明Spring正确的使用构造器注入的方式bean对象将dataSource注入OracleUserDAO对象内部, 并且有正确的执行结果。

5.4 完整代码

User类的完整代码如下所示:

package com.souvc.entity;import java.io.Serializable;  public class User implements Serializable {    private int id;    private String name;    private String pwd;    private String phone;        public User() {    }    public User(int id, String name, String pwd, String phone) {      this.id = id;      this.name = name;      this.pwd = pwd;      this.phone = phone;    }    public User(String name, String pwd, String phone) {      super();      this.name = name;      this.pwd = pwd;      this.phone = phone;    }    public int getId() {      return id;    }    public void setId(int id) {      this.id = id;    }    public String getName() {      return name;    }    public void setName(String name) {      this.name = name;    }    public String getPwd() {      return pwd;    }    public void setPwd(String pwd) {      this.pwd = pwd;    }    public String getPhone() {      return phone;    }    public void setPhone(String phone) {      this.phone = phone;    }    @Override    public int hashCode() {      return id;    }    @Override    public boolean equals(Object obj) {      if (this == obj)        return true;      if (obj == null)        return false;      if (obj instanceof User) {        User o = (User) obj;        return this.id == o.id;      }      return true;    }        @Override    public String toString() {      return id+","+name+","+pwd+","+phone;    }  }

oracle.sql文件的完整代码如下所示:

 

UserDAO文件的完整代码如下所示:

package com.souvc.dao;import com.souvc.entity.User;/** * 用户数据访问对象接口 */public interface UserDAO {  /** 根据唯一用户名查询系统用户, 如果没有找到用户信息返回null */  public User findByName(String name);}

OracleUserDAO文件的完整代码如下所示:

 

applicationContext.

<?  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/context"  ="http://www.springframework.org/schema/jdbc"  ="http://www.springframework.org/schema/jee"  ="http://www.springframework.org/schema/tx"  ="http://www.springframework.org/schema/data/jpa"  xsi:schemaLocation="      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd      http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">  <!-- setter注入 oracle     <bean id="dataSource" class="com.souvc.dao.JDBCDataSource">    <property name="driver" value="oracle.jdbc.OracleDriver"></property>    <property name="url"    value="jdbc:oracle:thin:@localhost:1521:ora1">    </property>    <property name="user" value="root"></property>    <property name="pwd" value="123456"></property>    </bean>  -->  <!-- setter注入 mysql -->  <bean id="dataSource" class="com.souvc.dao.JDBCDataSource">    <property name="driver" value="com.mysql.jdbc.Driver"></property>    <property name="url"      value="jdbc:mysql://localhost:3306/cnblogs">    </property>    <property name="user" value="root"></property>    <property name="pwd" value="123456"></property>  </bean>  <!-- 构造器注入 -->  <bean id="userDAO" class="com.souvc.dao.MysqlUserDAO">    <!-- 利用构造器参数注入bean的属性 -->    <constructor-arg name="dataSource" ref="dataSource" />  </bean></beans>

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:Spring IOC容器

关键词:Spring

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录