[跟我学spring学习笔记][更多DI知识]
延迟初始化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知识]的更多相关文章
- [跟我学Spring学习笔记][DI配置与使用]
DI 依赖和依赖注入 定义 传统的依赖一般指"类之间的关系",那先让我们复习一下类之间的关系: 泛化:表示类与类之间的继承关系.接口与接口之间的继承关系: 实现:表示类对接口的实现 ...
- [跟我学spring学习笔记][DI循环依赖]
循环依赖 什么是循环依赖? 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢? ...
- [跟我学spring学习笔记][IoC]
IoC基础 什么是IoC Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想. ioc做什么 IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找 ...
- Spring学习笔记1——基础知识 (转)
1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书<Expert one-on-one J2EE Design and Deve ...
- Spring学习笔记1——基础知识
1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书<Expert one-on-one J2EE Design and Deve ...
- spring学习笔记(一) Spring概述
博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书. 强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...
- Java架构师之路 Spring学习笔记(一) Spring介绍
前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...
- Spring学习笔记之依赖的注解(2)
Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Com ...
- Spring学习笔记2——表单数据验证、文件上传
在上一章节Spring学习笔记1——IOC: 尽量使用注解以及java代码中,已经搭建了项目的整体框架,介绍了IOC以及mybatis.第二节主要介绍SpringMVC中的表单数据验证以及文件上传. ...
随机推荐
- .NET 4.0 兼容 .NET 2.0 的方法
使用.net开发桌面应用,广大亲门最头疼的莫过于客户端部署的问题.基于.net 2.0 的winfrom程序因为 Framework 的分发包大小为20M左右还好解决,不幸的是如果项目中使用了Wcf, ...
- easyui treeJson 带层数
public string GetTreeNav(int ID,int Num) { StringBuilder sb = new StringBuilder(); sb.Append("[ ...
- Android-图标
首先需要申明一点,系统图标并不存在于项目资源中,而是存在于设备中. 这就带来一个大问题,界面风格的控制权交到了不同的设备手中.这是我们不愿意看到的. 如何解决这个问题?有两种方法: 1.创建自己的图标 ...
- (转) Python in NetBeans IDE 8.0
原地址: https://blogs.oracle.com/geertjan/entry/python_in_netbeans_ide_8 Copy this to the clipboard: ht ...
- tttt
while(scanf("%d",&n)!=EOF) { res=-1; level(tmp,n,res,1); printf("%d/n",res); ...
- php性能效率优化
[size=5][color=Red]php性能效率优化[/color][/size] 最近在公司一边自学一边写PHP程序,由于公司对程序的运行效率要求很高,而自己又是个新手,一开始就注意程序的效率很 ...
- 网上查了点关于windows注册表的知识,发现基本名词没理解好,于是整理这篇笔记(可能个别地方不准确,先这么理解吧),有了这个理解,再去看网上的文章,就差不读了
打开注册表编辑器,左边窗格中显示的是“注册表项”,右边窗格中显示的是“注册表项的项值” 子项:子项是相对父项而言的,在某一个项(父项)下面出现的项(子项) 值项:一个项可以有一个或多个项值,当前被使用 ...
- 论如何进CSDN博客排名前500
http://www.jtahstu.com/blog/post-71.html 目前该方法并不适用于博客园,显然写博客园的程序员智商要高些.
- mysql 高效分页控件及c#调用实例
第一.首先在mysql中创建一个存储过程 BEGIN /* @selectSql VARCHAR(5000), --sql语句 @orderWhere VARCHAR(200), --排序条件 @pa ...
- php平台移植windows和linux
2015/1/14 今天项目中遇到一个问题,在本地运行没有问题,挂到服务器上,就运行错误.过程中比较粗心,知道导致这样的原因,居然小时漏掉了一些细节. 比如,在php中通过声明__autoload() ...