延迟初始化Bean

定义:
延迟初始化也叫做惰性初始化,指不提前初始化Bean,在真正使用时才创建并初始化Bean

如何延迟:
配置方式很简单只需在标签上指定 “lazy-init” 属性值为“true”即可延迟初始化Bean。

默认为什么为不延迟或者说什么时候要延迟?:
Spring容器预先初始化Bean通常能帮助我们提前发现配置错误,所以如果没有什么情况建议开启,除非有某个Bean可能需要加载很大资源,而且很可能在整个应用程序生命周期中很可能使用不到,可以设置为延迟初始化。

配置例子如下:

<bean id="helloApi"
class="cn.javass.spring.chapter2.helloworld.HelloImpl"
lazy-init="true"/>

使用depends-on//以及了解init,destory

注意回销回调


什么是depens-on?:
depends-on是指指定Bean初始化及销毁时的顺序,使用depends-on属性指定的Bean要先初始化完毕后才初始化当前Bean,由于只有“singleton”Bean能被Spring管理销毁,所以当Bean都是“singleton”时,使用depends-on属性指定的Bean要在Bean之后销毁。

配置例子:

<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>
<bean id="decorator"
class="cn.javass.spring.chapter3.bean.HelloApiDecorator"
depends-on="helloApi">
<property name="helloApi"><ref bean="helloApi"/></property>
</bean>

用法:
“decorator”指定了“depends-on”属性为“helloApi”,所以在“decorator”Bean初始化之前要先初始化“helloApi”,而在销毁“helloApi”之前先要销毁“decorator”,大家注意一下销毁顺序,与文档上的不符。

“depends-on”属性可以指定多个Bean,若指定多个Bean可以用“;”、“,”、空格分割。

优点:
那“depends-on”有什么好处呢?主要是给出明确的初始化及销毁顺序,比如要初始化“decorator”时要确保“helloApi”Bean的资源准备好了(有可能仅靠Bean的初始化是不够的,比如文件没有打开好,你就操作文件了),否则使用“decorator”时会看不到准备的资源;而在销毁时要先在“decorator”Bean的把对“helloApi”资源的引用释放掉才能销毁“helloApi”,否则可能销毁 “helloApi”时而“decorator”还保持着资源访问,造成资源不能释放或释放错误。

例子:

在平常开发中我们可能需要访问文件系统,而文件打开、关闭是必须配对的,不能打开后不关闭,从而造成其他程序不能访问该文件。让我们来看具体配置吧:

1)准备测试类:

ResourceBean从配置文件中配置文件位置,然后定义初始化方法init中打开指定的文件,然后获取文件流;最后定义销毁方法destroy用于在应用程序关闭时调用该方法关闭掉文件流。

DependentBean中会注入ResourceBean,并从ResourceBean中获取文件流写入内容;定义初始化方法init用来定义一些初始化操作并向文件中输出文件头信息;最后定义销毁方法用于在关闭应用程序时想文件中输出文件尾信息。

2) 配置文件

<bean id="resourceBean"
class="cn.javass.spring.chapter2.helloworld.ResourceBean"
init-method="init" destroy-method="destory">
<property name="file" value="test.txt"/>
</bean>
<bean id="dependentBean"
class="cn.javass.spring.chapter2.helloworld.DependentBean"
init-method="init" destroy-method="destory" depends-on="resourceBean">
<property name="resourceBean" ref="resourceBean"/>
</bean>
  • \配置:Spring容器能自动把字符串转换为java.io.File。
  • init-method=”init” :指定初始化方法,在构造器注入和setter注入完毕后执行。
  • destroy-method=”destroy”:指定销毁方法,只有“singleton”作用域能销毁,“prototype”作用域的一定不能,其他作用域不一定能;后边再介绍。

Java代码

package cn.javass.spring.chapter3;
import java.io.IOException;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.javass.spring.chapter3.bean.DependentBean;
public class MoreDependencyInjectTest {
@Test
public void testDependOn() throws IOException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("chapter3/depends-on.xml");
//一点要注册销毁回调,否则我们定义的销毁方法不执行
context.registerShutdownHook();
DependentBean dependentBean =
context.getBean("dependentBean", DependentBean.class);
dependentBean.write("aaa");
}
}

自动装配

定义

自动装配就是指由Spring来自动地注入依赖对象,无需人工参与。

目前有4种自动装配的方式:

  • no 默认
  • byName
  • byType
  • constr uctor

其中Spring3.0已不推荐使用之前版本的“autodetect”自动装配,推荐使用Java 5+支持的(@Autowired)注解方式代替

好处:

自动装配的好处是减少构造器注入和setter注入配置,减少配置文件的长度。自动装配通过配置标签的“autowire”属性来改变自动装配方式

配置的含义:

  • default:使用默认的自动装配,默认的自动装配需要在标签使用default-autowire属性指定.

  • no:意思是不支持自动装配,指明依赖

  • byName:通过设置autowire=”byName’,意思是根据名字进行自动装配,只能用于setter注入.能替换property.

    比如我们有方法“setHelloApi”,则“byName”方式Spring容器将查找名字为helloApi的Bean并注入,如果找不到指定的Bean,将什么也不注入。

  • byType 通过设置Bean定义属性autowire=”byType”,意思是指根据类型注入,用于setter注入

    比如如果指定自动装配方式为“byType”,而“setHelloApi”方法需要注入HelloApi类型数据,则Spring容器将查找HelloApi类型数据,如果找到一个则注入该Bean,如果找不到将什么也不注入,如果找到多个Bean将优先注入标签“primary”属性为true的Bean,否则抛出异常来表明有个多个Bean发现但不知道使用哪个

    tips:

    根 据类型找到多个Bean时,对于集合类型(如List、Set)将注入所有匹配的候选者,而对于其他类型遇到这种情况可能需要使用“autowire- candidate”属性为false来让指定的Bean放弃作为自动装配的候选者,或使用“primary”属性为true来指定某个Bean为首选 Bean

    -constructor:通过设置Bean定义属性autowire=”constructor”,功能和“byType”功能一样,根据类型注入构造器参数,只是用于构造器注入方式.

    -autodetect: 已不使用

不是所有类型都能自动装配

自动装配注入方式能和配置注入方式一同工作吗?当然可以,大家只需记住配置注入的数据会覆盖自动装配注入的数据

不建议采用自动装配

自动装配也是有缺点的,最重要的缺点就是没有了配置,在查找注入错误时非常麻烦,还有比如基本类型没法完成自动装配,所以可能经常发生一些莫名其妙的错误,在此我推荐大家不要使用该方式,最好是指定明确的注入方式,或者采用最新的Java5+注解注入方式。所以大家在使用自动装配时应该考虑自己负责项目的复杂度来进行衡量是否选择自动装配方式。

依赖检查

定义:
上一节介绍的自动装配,很可能发生没有匹配的Bean进行自动装配,如果此种情况发生,只有在程序运行过程中发生了空指针异常才能发现错误,如果能提前发现该多好啊,这就是依赖检查的作用。

依赖检查:用于检查Bean定义的属性都注入数据了,不管是自动装配的还是配置方式注入的都能检查,如果没有注入数据将报错,从而提前发现注入错误,只检查具有setter方法的属性。

Spring3+也不推荐配置方式依赖检查了,建议采用Java5+ @Required注解方式,测试时请将XML schema降低为2.5版本的,和自动装配中“autodetect”配置方式的xsd一样。

不推荐 :也懒得仔细学了

方法注入(看不懂)

所谓方法注入其实就是通过配置方式覆盖或拦截指定的方法,通常通过代理模式实现。Spring提供两种方法注入:查找方法注入和方法替换注入。

因为Spring是通过CGLIB动态代理方式实现方法注入,也就是通过动态修改类的字节码来实现的,本质就是生成需方法注入的类的子类方式实现。
在进行测试之前,我们需要确保将“ccm.springsource.cn.sf.cglib-2.2.0.jar”放到lib里并添加到“Java
Build Path”中的Libararies中。否则报错,异常中包含“nested exception is
java.lang.NoClassDefFoundError: cn/sf/cglib/proxy/CallbackFilter”。

查找方法注入

一、查找方法注入:又称为Lookup方法注入,用于注入方法返回结果,也就是说能通过配置方式替换方法返回结果。使用配置;其中name属性指定方法名,bean属性指定方法需返回的Bean。

方法定义格式:访问级别必须是public或protected,保证能被子类重载,可以是抽象方法,必须有返回值,必须是无参数方法,查找方法的类和被重载的方法必须为非final:

替换方法注入

二、替换方法注入:也叫“MethodReplacer”注入,和查找注入方法不一样的是,他主要用来替换方法体。通过首先定义一个MethodReplacer接口实现,然后如下配置来实现:

[跟我学spring学习笔记][更多DI知识]的更多相关文章

  1. [跟我学Spring学习笔记][DI配置与使用]

    DI 依赖和依赖注入 定义 传统的依赖一般指"类之间的关系",那先让我们复习一下类之间的关系: 泛化:表示类与类之间的继承关系.接口与接口之间的继承关系: 实现:表示类对接口的实现 ...

  2. [跟我学spring学习笔记][DI循环依赖]

    循环依赖 什么是循环依赖? 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢? ...

  3. [跟我学spring学习笔记][IoC]

    IoC基础 什么是IoC Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想. ioc做什么 IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找 ...

  4. Spring学习笔记1——基础知识 (转)

    1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书<Expert one-on-one J2EE Design and Deve ...

  5. Spring学习笔记1——基础知识

    1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书<Expert one-on-one J2EE Design and Deve ...

  6. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  7. Java架构师之路 Spring学习笔记(一) Spring介绍

    前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...

  8. Spring学习笔记之依赖的注解(2)

    Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Com ...

  9. Spring学习笔记2——表单数据验证、文件上传

    在上一章节Spring学习笔记1——IOC: 尽量使用注解以及java代码中,已经搭建了项目的整体框架,介绍了IOC以及mybatis.第二节主要介绍SpringMVC中的表单数据验证以及文件上传. ...

随机推荐

  1. dataset导出成excel

    之前网上查找了很多关于这类的代码.要不是中文乱码,要不是就是太复杂.这个是我用过最好用的. //ds为数据源,filename为保存的文件名 publicvoidCreateExcel(DataSet ...

  2. CSS基础知识之float

    前段时间写过一篇CSS基础知识之position,当时对float的理解不太准确,被慕课网多名读者指出(原文已修正,如有误导实在抱歉).现对float进行更深入的学习,在此把学习心得分享给大家. 浮动 ...

  3. MVC笔记

    简要论述对MVC模式的理解,并简述ThinkPHP中的MVC模式是如何运行的 MVC(Model-View-Controller)应用程序结构被用来分析分布式应用程序的特征.这种抽象结构能有助于将应用 ...

  4. ios swift(1)冒泡排序

    //冒泡排序  稳定性最高  时间复杂度高 O(n(2)) ,交换次数太多, 一次交换等于三次赋值    最简单 var count = 0 func sortInts(inout data : [I ...

  5. CODEVS 1066/洛谷 P1514引水入城

    1066 引水入城 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在一个遥远的国 ...

  6. Android电子书翻页效果实现

    这篇文章是在参考了别人的博客基础上,修改了其中一个翻页bug,并且加了详细注释 先看效果 其中使用了贝赛尔曲线原理,关于贝赛尔曲线的知识,推荐大家看下http://blog.csdn.net/hmg2 ...

  7. 搭建hbase-0.94.26集群环境

    先安装hadoop1.2.1,见http://blog.csdn.net/jediael_lu/article/details/38926477 1.配置hbase-site.xml <prop ...

  8. setTimeout与setInterval方法的区别

    setTimeout与setInterval方法的区别 setTimeout()用于设定在指定的时间之后执行对应的函数或代码.,在全局作用域下执行 setTimeout(code,time[,args ...

  9. MySQL错误Another MySQL daemon already running with the same unix socket

    今天遇到RT这个问题后,导致数据库错误,然后在国外网站发现了一个解决方法,记录如下: 原因是:多个Mysql进程使用了同一个socket. 解决方法是:直接把mysql.sock文件改名即可.也可以删 ...

  10. 在Ubuntu上安装VmTools

    1.添加VmTools 2.解压 .tag.gz文件 使用Linux命令: tar –zxvf src –c dis -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 ...