平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。
 
spring有多种依赖注入的形式,下面仅介绍spring通过xml进行IOC配置的方式:
  • Set注入
这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口):
  1. package com.bless.springdemo.action;
  2. public class SpringAction {
  3. //注入对象springDao
  4. private SpringDao springDao;
  5. //一定要写被注入对象的set方法
  6. public void setSpringDao(SpringDao springDao) {
  7. this.springDao = springDao;
  8. }
  9. public void ok(){
  10. springDao.ok();
  11. }
  12. }
 
随后编写spring的xml文件,<bean>中的name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在<bean>标签中创建一个<property>标签指定SpringDao。<property>标签中的name就是SpringAction类中的SpringDao属性名,ref指下面<bean name="springDao"...>,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入:
  1. <!--配置bean,配置后该类由spring管理-->
  2. <bean name="springAction" class="com.bless.springdemo.action.SpringAction">
  3. <!--(1)依赖注入,配置当前类中相应的属性-->
  4. <property name="springDao" ref="springDao"></property>
  5. </bean>
  6. <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
  
 
  • 构造器注入
这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:
  1. public class SpringAction {
  2. //注入对象springDao
  3. private SpringDao springDao;
  4. private User user;
  5. public SpringAction(SpringDao springDao,User user){
  6. this.springDao = springDao;
  7. this.user = user;
  8. System.out.println("构造方法调用springDao和user");
  9. }
  10. public void save(){
  11. user.setName("卡卡");
  12. springDao.save(user);
  13. }
  14. }
 
在XML文件中同样不用<property>的形式,而是使用<constructor-arg>标签,ref属性同样指向其它<bean>标签的name属性:
  1. <!--配置bean,配置后该类由spring管理-->
  2. <bean name="springAction" class="com.bless.springdemo.action.SpringAction">
  3. <!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->
  4. <constructor-arg ref="springDao"></constructor-arg>
  5. <constructor-arg ref="user"></constructor-arg>
  6. </bean>
  7. <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
  8. <bean name="user" class="com.bless.springdemo.vo.User"></bean>
  解决构造方法参数的不确定性,你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理:
下面是设置index,就是参数位置:
  1. <bean name="springAction" class="com.bless.springdemo.action.SpringAction">
  2. <constructor-arg index="0" ref="springDao"></constructor-arg>
  3. <constructor-arg index="1" ref="user"></constructor-arg>
  4. </bean>
  另一种是设置参数类型:
  1. <constructor-arg type="java.lang.String" ref=""/>
  • 静态工厂的方法注入
静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取:
  1. package com.bless.springdemo.factory;
  2. import com.bless.springdemo.dao.FactoryDao;
  3. import com.bless.springdemo.dao.impl.FactoryDaoImpl;
  4. import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl;
  5. public class DaoFactory {
  6. //静态工厂
  7. public static final FactoryDao getStaticFactoryDaoImpl(){
  8. return new StaticFacotryDaoImpl();
  9. }
  10. }
 
同样看关键类,这里我需要注入一个FactoryDao对象,这里看起来跟第一种注入一模一样,但是看随后的xml会发现有很大差别:
  1. public class SpringAction {
  2. //注入对象
  3. private FactoryDao staticFactoryDao;
  4. public void staticFactoryOk(){
  5. staticFactoryDao.saveFactory();
  6. }
  7. //注入对象的set方法
  8. public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
  9. this.staticFactoryDao = staticFactoryDao;
  10. }
  11. }
 
Spring的IOC配置文件,注意看<bean name="staticFactoryDao">指向的class并不是FactoryDao的实现类,而是指向静态工厂DaoFactory,并且配置 factory-method="getStaticFactoryDaoImpl"指定调用哪个工厂方法:
  1. <!--配置bean,配置后该类由spring管理-->
  2. <bean name="springAction" class="com.bless.springdemo.action.SpringAction" >
  3. <!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)-->
  4. <property name="staticFactoryDao" ref="staticFactoryDao"></property>
  5. </property>
  6. </bean>
  7. <!--(3)此处获取对象的方式是从工厂类中获取静态方法-->
  8. <bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>
 
 
 
  • 实例工厂的方法注入
实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法:
  1. public class DaoFactory {
  2. //实例工厂
  3. public FactoryDao getFactoryDaoImpl(){
  4. return new FactoryDaoImpl();
  5. }
  6. }
那么下面这个类没什么说的,跟前面也很相似,但是我们需要通过实例工厂类创建FactoryDao对象:
  1. public class SpringAction {
  2. //注入对象
  3. private FactoryDao factoryDao;
  4. public void factoryOk(){
  5. factoryDao.saveFactory();
  6. }
  7. public void setFactoryDao(FactoryDao factoryDao) {
  8. this.factoryDao = factoryDao;
  9. }
  10. }
 
最后看spring配置文件:
  1. <!--配置bean,配置后该类由spring管理-->
  2. <bean name="springAction" class="com.bless.springdemo.action.SpringAction">
  3. <!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)-->
  4. <property name="factoryDao" ref="factoryDao"></property>
  5. </bean>
  6. <!--(4)此处获取对象的方式是从工厂类中获取实例方法-->
  7. <bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean>
  8. <bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean>
 
 
  • 总结
Spring IOC注入方式用得最多的是(1)(2)种,多谢多练就会非常熟练。
        另外注意:通过Spring创建的对象默认是单例的,如果需要创建多实例对象可以在<bean>标签后面添加一个属性:
  1. <bean name="..." class="..." scope="prototype">

Spring Bean学习创建及使用<二>的更多相关文章

  1. Spring Bean学习创建及使用<一>

    转自:http://glzaction.iteye.com/blog/1299441 Spring中依赖注入有三种注入方式: 一.构造器注入: 二.设值注入(setter方式注入): 三.Feild方 ...

  2. Spring MVC 学习 -- 创建过程

    Spring MVC 学习 -- 创建过程 Spring MVC我们使用的时候会在web.xml中配置 <servlet> <servlet-name>SpringMVC< ...

  3. Spring 源码(10)Spring Bean 的创建过程(1)

    Spring Bean的创建刚开始进行了一些准备工作,比如转换服务的初始化,占位符解析器的初始化,BeanDefinition元数据的冻结等操作,都是为了在创建Bean的过程中保证Bean的正确的创建 ...

  4. Spring 源码(11)Spring Bean 的创建过程(2)

    Spring Bean 的创建过程介绍了FactoryBean 的创建方式,那么接下来介绍不是FactoryBean的创建方式,在创建过程中,又会分为单例的Bean的创建,原型类型的Bean的创建等. ...

  5. Spring 源码(12)Spring Bean 的创建过程(3)

    继续上一篇Spring Bean的创建过程的解读,上一篇介绍了Spring在创建过程中doGetBean方法,在执行过程中会调用getSingleton方法并且设置一个lambda表达式,这个lamb ...

  6. Spring 源码(13)Spring Bean 的创建过程(4)

    Spring Bean的创建过程非常的复杂,上一篇重点介绍了Spring在创建Bean的过程中,使用InstantiationBeanPostProcessor进行提前创建Bean,我们可以通过CGL ...

  7. Spring———bean的创建方式,注入方式,复杂类型注入 概括

    Spring相关概念和类    1.IOC             inverse of control    控制反转   反转了创建对象的方式            以前:new 对象,管理和维护 ...

  8. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

  9. Spring 源码(14)Spring Bean 的创建过程(6)对象的提前暴露

    知识回顾 解析完Bean信息的合并,可以知道Spring在实例化Bean之后,属性填充前,对Bean进行了Bean的合并操作,这里的操作主要做了对Bean对象标记了@Autowired.@Value. ...

随机推荐

  1. go语言json转map

    package util import ( "encoding/json" "fmt" ) // json转map函数,通用 func JSONToMap(st ...

  2. Odoo的菜单项

    用户界面的入口是菜单项,菜单项形成一个层级结构,最顶级项为应用,其下一级为每个应用的主菜单.还可以添加更深的子菜单.可操作菜单与窗口操作关联,它告诉客户端在点击了菜单项后应执行什么操作. 菜单项存储在 ...

  3. oracle学习1 基于oracle数据库的PLSQL编程以及存储过程的创建和使用视频

    https://www.bilibili.com/video/av46777605 plsql中选择testWindow中可以进行测试 1.编写函数在plsql的testwindow中 begin d ...

  4. QTP(12)

    练习:录制两位数加法器加法计算后退出的步骤,对两个加数做随机数参数化,随机数范围是0-50,在计算后获得被测系统计算的结果,判断如果结果等于100,msgbox提示“满分”,如果结果在80和99之间, ...

  5. QTP(10)

    一.VBS语言基础 1.运算符和表达式 (1)运算符 (2)表达式 a.数学表达式:由算术运算符连接,计算结果为数字 b.字符串表达式:由字符串连接符连接,计算结果为字符串 c.条件表达式:由关系运算 ...

  6. zencart批量评论插件Easy Populate CSV add reviews使用教程

    此插件在Easy Populate CSV 1.2.5.7b产品批量插件基础上开发,有1.3x与1.5x两个版本. zencart批量评论插件Easy Populate CSV add reviews ...

  7. Web界面开发必看!Kendo UI for jQuery编辑功能指南第二弹

    Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support f ...

  8. VMware 虚拟机下载与安装

    虚拟机下载 VMware官网地址:https://www.vmware.com/ 进行官网后,点击左边的下载图标,然后 根据操作系统选择合适的产品,在这里以Windows系统为例,点击转至下载,如下图 ...

  9. php类知识点滴---类的实例化,构造函数,继承初步

    实例化类----黑科技用法,通过字符串来实例化 class coach { public function __construct() { echo "欢迎光临北武堂"." ...

  10. tornado框架自定义中间件过程中的一些基础技术(1)

    为了检查当前请求是否在用户的权限列表中,我们需要获取uri(也就是当前链接),下列代码说明了获取的过程,也证明了python魔术方法的重要性class testHandler(RequestHandl ...