一、依赖注入的三种方式
      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来。另一类则是依赖注入。
一般而言,依赖注入可分为3中方式:

  • 构造器注入
  • setter注入
  • 接口注入

构造器注入和setter注入是主要的注入方式,而接口注入是从别的地方注入的方式,比如,在Web工程中,配置的数据源往往是通过服务器(比如tomcat)
去配置的,这个时候可以用JNDI(Java Naming and Directory interface)的形式通过接口将它注入Spring IoC容器中来,下面就是对它们进行详解。

1、构造器注入
      构造器注入依赖于构造方法实现,而构造方法是可以是有参构造或无参构造。在大部分情况下,我们都是通过类的构造方法来创建类的对象,Spring也可以采用反射的方式,
通过使用构造方法完成注入,这就是构造器注入的原理。
为了让Spring完成对应的构造注入,我们由必要取描述具体的类,构造方法并设置对应的参数,这样Spring就会通过对应的信息用反射的形式创建对象。

2、使用setter注入
    setter注入是Spring中最主流的注入方式,它利用Java Bean规范所定义的setter方法来完成注入,灵活且可读性高。它消除了使用构造器注入时出现多个参数的可能性,
首先可以把构造方法声明为无参构造,然后使用setter注入为其设置对应的值,其实也是通过Java反射技术得以实现的。

3、接口注入
     有时候资源并不是来至自身系统,而是来至外界,比如数据库连接资源完全可以在tomcat下配置,单后通过JNDI的形式去获取它,这样数据库连接资源是属于开发工程外的资源,这个时候我们
可以采用接口注入的形式来获取它,比如在tomcat中可以配置参数数据源,又如在Eclipse中配置了tomcat后,可以打开服务器的context.xml文件。

二、三种注入方式的测试案例

总的配置文件:applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 依赖注入·构造器注入 -->
<bean id="user_xfwl" class="com.xfwl.spring.DI.UserBean">
<constructor-arg index="0" value="小风微凉"/>
<constructor-arg index="1" value="123456"/>
</bean>
<!-- 依赖注入·setter注入 -->
<bean id="admin_xfwl" class="com.xfwl.spring.DI.Administrators">
<property name="aid" value="100001"></property>
<property name="aname" value="小风微凉"></property>
<property name="apwd" value="123456"></property>
</bean>
<bean id="dao" class="com.xfwl.spring.DI.DAO">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@***.36.17.**:1521:***"/>
<property name="username" value="***"/>
<property name="password" value="***"/>
</bean>
<bean id="daoImpl" class="com.xfwl.spring.DI.LoginDaoImp">
<property name="dao" ref="dao"/>
</bean> <!-- 依赖注入·接口注入 -->
<!-- 配置数据源,使用C3P0连接池 的接口注入实现-->
<bean name="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!-- 指定连接池中保留的[最大连接数]. Default:15-->
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
<!-- 指定连接池中保留的[最小连接数]-->
<property name="minPoolSize" value="${jdbc.minPoolSize}"/>
<!-- 指定连接池的初[始化连接数] 取值应在minPoolSize 与 maxPoolSize 之间.Default:3-->
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
<!-- [最大空闲时间],60秒内未使用则连接被丢弃。若为0则永不丢弃。 Default:0-->
<property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>
<!-- 当连接池中的连接耗尽的时候c3p0[一次同时获取的连接数]. Default:3-->
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<!--
JDBC的标准,用以控制数据源内加载的PreparedStatements数量。
但由于预缓存的statements属于单个connection而不是整个连接池所以设置这个参数需要考虑到多方面的因数.
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:0
-->
<property name="maxStatements" value="${jdbc.maxStatements}"/>
<!-- 每60秒检查所有连接池中的[空闲连接].Default:0 -->
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
</bean>
</beans>

 1、构造器注入

 package com.xfwl.spring.DI;
/**
* 测试依赖注入-构造器注入
* @function
* @author 小风微凉
* @time 2018-7-10 下午2:17:16
*/
public class UserBean {
private String uname;
private String upwd;
//无参构造
public UserBean(){}
//有参构造
public UserBean(String uname,String upwd){
this.uname=uname;
this.upwd=upwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
@Override
public String toString() {
return "UserBean [uname=" + uname + ", upwd=" + upwd + "]";
}
}

配置文件:

 <!-- 依赖注入·构造器注入 -->
<bean id="user_xfwl" class="com.xfwl.spring.DI.UserBean">
<constructor-arg index="0" value="小风微凉"/>
<constructor-arg index="1" value="123456"/>
</bean>

2、使用setter注入

 package com.xfwl.spring.DI;
/**
* 依赖注入·setter注入
* @function
* @author 小风微凉
* @time 2018-7-10 下午2:37:54
*/
public class Administrators {
private String aid;
private String aname;
private String apwd; public Administrators(){} public String getAid() {
return aid;
} public void setAid(String aid) {
this.aid = aid;
} public String getAname() {
return aname;
} public void setAname(String aname) {
this.aname = aname;
} public String getApwd() {
return apwd;
} public void setApwd(String apwd) {
this.apwd = apwd;
} @Override
public String toString() {
return "Administrators [aid=" + aid + ", aname=" + aname + ", apwd="
+ apwd + "]";
} }

测试使用setter注入连接数据库,实现一次查询

创建一个DAO.java

 package com.xfwl.spring.DI;

 import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException; /**
* 登录连接DAO
* @function
* @author 小风微凉
* @time 2018-7-10 下午3:21:43
*/
public class DAO {
private String driverClassName;
private String url;
private String username;
private String password;
/**
* 获取数据库连接
* @param driverClassName
*/
public Connection getConn(){
Connection con=null;
try{
//加载Oracle的驱动类
Class.forName(driverClassName) ;
con =DriverManager.getConnection(url , username , password ) ;
}catch(SQLException ex){
System.out.println("数据库连接失败!");
ex.printStackTrace() ;
} catch (ClassNotFoundException e) { System.out.println("数据库连接失败!");
e.printStackTrace() ;
}
return con;
}
/**
* 释放数据库连接
* @param driverClassName
*/
public void releaseConn(Connection conn){
try {
if(!conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}

创建一个LoginDaoImp.java

 package com.xfwl.spring.DI;

 import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; /**
* 登录DAO
* @function
* @author 小风微凉
* @time 2018-7-10 下午3:21:43
*/
public class LoginDaoImp {
private DAO dao;
public void queryCstListByNo(String cstNo) throws SQLException{
Connection conn=dao.getConn();
String sql="SELECT CIF_CSTNO,CIF_HOSTNO,CIF_NAMECN FROM CB_CST_INF WHERE CIF_CSTNO=?";
PreparedStatement pst=conn.prepareStatement(sql);
pst.setString(1, cstNo);
ResultSet result=pst.executeQuery();
while(result.next()){
System.out.println("企业客户号:"+result.getString("CIF_CSTNO"));
System.out.println("核心客户号:"+result.getString("CIF_HOSTNO"));
System.out.println("客户名称:"+result.getString("CIF_HOSTNO"));
}
dao.releaseConn(conn);
}
public DAO getDao() {
return dao;
}
public void setDao(DAO dao) {
this.dao = dao;
}
}

配置文件:

 <!-- 依赖注入·setter注入 -->
<bean id="admin_xfwl" class="com.xfwl.spring.DI.Administrators">
<property name="aid" value="100001"></property>
<property name="aname" value="小风微凉"></property>
<property name="apwd" value="123456"></property>
</bean>
<bean id="dao" class="com.xfwl.spring.DI.DAO">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@***.36.17.**:1521:***"/>
<property name="username" value="***"/>
<property name="password" value="***"/>
</bean>
<bean id="daoImpl" class="com.xfwl.spring.DI.LoginDaoImp">
<property name="dao" ref="dao"/>
</bean>

3、接口注入

接口注入,关键是将第三方的外部资源注入到到我们想要的地方,关键是如何把数据信息注入到第三方资源对象中,然后再把第三方资源对象注入到指定的地方。

关键点在于配置文件:

 <!-- 依赖注入·接口注入 -->
<!-- 配置数据源,使用C3P0连接池 的接口注入实现-->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!-- 指定连接池中保留的[最大连接数]. Default:15-->
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
<!-- 指定连接池中保留的[最小连接数]-->
<property name="minPoolSize" value="${jdbc.minPoolSize}"/>
<!-- 指定连接池的初[始化连接数] 取值应在minPoolSize 与 maxPoolSize 之间.Default:3-->
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
<!-- [最大空闲时间],60秒内未使用则连接被丢弃。若为0则永不丢弃。 Default:0-->
<property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>
<!-- 当连接池中的连接耗尽的时候c3p0[一次同时获取的连接数]. Default:3-->
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<!--
JDBC的标准,用以控制数据源内加载的PreparedStatements数量。
但由于预缓存的statements属于单个connection而不是整个连接池所以设置这个参数需要考虑到多方面的因数.
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:0
-->
<property name="maxStatements" value="${jdbc.maxStatements}"/>
<!-- 每60秒检查所有连接池中的[空闲连接].Default:0 -->
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
</bean>

稍微分析一下:

  id:SpringIoc容器中配置的Bean对象。

 class:第三方资源对象的接口全路径。

  property :注入到第三方资源对象的数据。 

创建一个测试类:TestBean.java  

 package com.xfwl.spring.DI;
import java.sql.SQLException; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext; /**
* Spring Ioc测试
* @function
* @author 小风微凉
* @time 2018-7-10 上午9:55:15
*/
public class TestBean {
//绝对路径:FileSystemXmlApplicationContext
private static final String xmlAbsPath="E:/JAVA学习[【进阶学习】/JAVA回炉深造/进阶测试工作空间/多线程/SpringSources/src/com/xfwl/spring/DI/applicationContext.xml";
//项目相对路径:ClassPathXmlApplicationContext/ApplicationContext
private static final String xmlRelPath="com/xfwl/spring/DI/applicationContext.xml";
public static void main(String[] args) throws SQLException {
//拿到解析对象
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext(xmlRelPath);
//【1】构造器注入-拿到Bean对象
//UserBean user=(UserBean) ctx.getBean("user_xfwl");
//System.out.println(user.toString());
//【2】setter注入-拿到Bean对象
//Administrators admin=(Administrators) ctx.getBean("admin_xfwl");
//System.out.println(admin.toString());
//【3】接口注入-拿到Bean对象
LoginDaoImp daoImpl=(LoginDaoImp) ctx.getBean("daoImpl");
daoImpl.queryCstListByNo("CB10000929"); }
}

 测试结果:经过数据脱敏后的结果显示

 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
企业客户号:CB10000929,核心客户号:***********客户名称:赏渝沃舜汪物技术柔限星司,
企业客户号:CB10000764,核心客户号:***********客户名称:李靖,
企业客户号:CB10000720,核心客户号:***********客户名称:李靖333,
企业客户号:CB10000926,核心客户号:***********客户名称:赏渝沃舜汪物技术柔限星司,
企业客户号:CB10000927,核心客户号:***********客户名称:赏渝沃舜汪物技术柔限星司,
企业客户号:CB10000931,核心客户号:***********客户名称:赏渝沃舜汪物技术柔限星司,
企业客户号:CB10000940,核心客户号:***********客户名称:赏渝沃舜汪物技术柔限星司, 

JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配的更多相关文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件

    一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...

  2. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)

    一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...

  3. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解

    一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...

  5. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解

    一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)

    一. 装配Bean概述  关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...

  7. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)

    一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean

    一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式

    一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景.   2. ...

随机推荐

  1. (转)Android和JavaScript互相调用

    Html页面和Java代码结合的方式一般用在界面经常被更改 的情况下,可以讲html放在网络中,软件一打开就会访问网络获取到最新的界面.缺点是会受到网络信号的影响,从而导致访问速度慢. 1.用WebV ...

  2. cxGrid使用汇总3

    32根据单元的值设置样式   解决:procedure   <aForm>.<aColumn>StylesGetContentStyle(         Sender:   ...

  3. AzureStack混合云大数据解决方案

    AzureStack是Azure的私有云解决方案.AzureStack可以帮助用户实现混合云的部署模式. 本文将介绍混合云的模式下,Azure作为计算资源,AzureStack作为存储资源.如下图: ...

  4. TCP之四:TCP 滑动窗口协议 详解

    滑动窗口机制 滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口:同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口.发送窗口和接收窗口的序号的 ...

  5. 1136 A Delayed Palindrome

    题意:略. 思路:大整数相加,回文数判断.对首次输入的数也要判断其是否是回文数,故这里用do...while,而不用while. 代码: #include <iostream> #incl ...

  6. python开发面向对象基础:接口类&抽象类&多态&钻石继承

    一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...

  7. Struts2接受页面传值过程中出现input的问题

    其实我在使用Struts2的时候,遇到要求返回input的时候不算少.一般我们在使用Struts2的时候,都会返回SUCCESS/ERROR,或者是NONE以到Strtuts的配置文件中再进行相应的处 ...

  8. C#获取视频文件播放长度

    下面两种方法只支持部分视频格式,一般格式mp3,wma等等支持 1.使用Shell32 添加引用,选择COM中的Microsoft Shell Controls And Automation引用 // ...

  9. PHP文件操作(三)-文件的写入

    fwrite()  //对文件进行写入 fwrite(file,string,length)file:必选项,需要写入的文件string:必选项,规定要写入文件的字符串length:可选项,规定要写入 ...

  10. JavaScript高级程序设计学习

    1.变量 变量使用var操作符定义,var message,定义一个message变量,可用来保存任何类型的变量.未经初始化的变量值为undifided: 如果没变量没有被var定义,那么被执行后会成 ...