信用卡网站建设,微信网页版登录手机版,wordpress模板 菜谱,前端网站开发工具一. 延迟初始化 延迟初始化也叫做惰性初始化#xff0c;指不提前初始化Bean#xff0c;而是只有在真正使用时才创建及初始化Bean。配置方式很简单只需在bean标签上指定 “lazy-init” 属性值为“true”即可延迟初始化Bean Spring容器会在创建容器时提前初始化“singl… 一. 延迟初始化 延迟初始化也叫做惰性初始化指不提前初始化Bean而是只有在真正使用时才创建及初始化Bean。配置方式很简单只需在bean标签上指定 “lazy-init” 属性值为“true”即可延迟初始化Bean Spring容器会在创建容器时提前初始化“singleton”作用域的Bean“singleton”就是单例的意思即整个容器 每个Bean只有一个实例后边会详细介绍。Spring容器预先初始化Bean通常能帮助我们提前发现配置错误所以如果 没有什么情况建议开启除非有某个Bean可能需要加载很大资源而且很可能在整个应用程序生命周期中很可能使用不 到可以设置为延迟初始化。延迟初始化的Bean通常会在第一次使用时被初始化或者在被非延迟初始化Bean作为依赖对象注入时在会随着初 始化该Bean时被初始化因为在这时使用了延迟初始化Bean。 容器管理初始化Bean消除了编程实现延迟初始化完全由容器控制只需在需要延迟初始化的Bean定义上配置即 可比编程方式更简单而且是无侵入代码的。 bean idhelloApi
classcn.javass.spring.chapter2.helloworld.HelloImpl
lazy-inittrue/ 二. 使用depends-on depends-on是指指定Bean初始化及销毁时的顺序使用depends-on属性指定的Bean要先初始化完毕后才初始 化当前Bean由于只有“singleton”Bean能被Spring管理销毁所以当指定的Bean都是“singleton”时使用 depends-on属性指定的Bean要在指定的Bean之后销毁. bean idhelloApi classcn.javass.spring.chapter2.helloworld.HelloImpl/
bean iddecorator classcn.javass.spring.chapter3.bean.HelloApiDecorator depends-onhelloApi property namehelloApiref beanhelloApi//property
/bean 说明“decorator”指定了“depends-on”属性为“helloApi”所以在“decorator”Bean初始化之前要先初始化 “helloApi”而在销毁“helloApi”之前先要销毁“decorator”。 “depends-on”属性可以指定多个Bean若指定多个Bean可以用“;”、“,”、空格分割。 那“depends-on”有什么好处呢主要是给出明确的初始化及销毁顺序比如要初始化“decorator”时要确保 “helloApi”Bean的资源准备好了否则使用“decorator”时会看不到准备的资源而在销毁时要先在 “decorator”Bean的把对“helloApi”资源的引用释放掉才能销毁“helloApi”否则可能销毁 “helloApi”时而 “decorator”还保持着资源访问造成资源不能释放或释放错误。 举例说明 在平常开发中我们可能需要访问文件系统而文件打开、关闭是必须配对的不能打开后不关 闭从而造成其他程序不能访问该文件。让我们来看具体配置吧 1. 准备测试类 1 public class ResourceBean { 2 private FileOutputStream fos; 3 private File file; 4 //初始化方法 5 public void init() { 6 System.out.println(ResourceBean:初始化); 7 //加载资源,在此只是演示 8 System.out.println(ResourceBean:加载资源执行一些预操作); 9 try {
10 this.fos new FileOutputStream(file);
11 } catch (FileNotFoundException e) {
12 e.printStackTrace();
13 }
14 }
15 //销毁资源方法
16 public void destroy() {
17 System.out.println(ResourceBean:销毁);
18 //释放资源
19 System.out.println(ResourceBean:释放资源执行一些清理操作);
20 try {
21 fos.close();
22 } catch (IOException e) {
23 e.printStackTrace();
24 }
25 }
26 public FileOutputStream getFos() {
27 return fos;
28 }
29 public void setFile(File file) {
30 this.file file;
31 }
32 } View Code 1 public class DependentBean { 2 ResourceBean resourceBean; 3 public void write(String ss) throws IOException { 4 System.out.println(DependentBean:写资源); 5 resourceBean.getFos().write(ss.getBytes()); 6 } 7 //初始化方法 8 public void init() throws IOException { 9 System.out.println(DependentBean:初始化);
10 resourceBean.getFos().write(DependentBean:初始化.getBytes());
11 }
12 //销毁方法
13 public void destroy() throws IOException {
14 System.out.println(DependentBean:销毁);
15 //在销毁之前需要往文件中写销毁内容
16 resourceBean.getFos().write(DependentBean:销毁.getBytes());
17 }
18
19 public void setResourceBean(ResourceBean resourceBean) {
20 this.resourceBean resourceBean;
21 }
22 } View Code 说明 ResourceBean从配置文件中配置文件位置然后定义初始化方法init中打开指定的文件然后获取文件流最后定义销 毁方法destroy用于在应用程序关闭时调用该方法关闭掉文件流。 DependentBean中会注入ResourceBean并从ResourceBean中获取文件流写入内容定义初始化方法init用来定义 一些初始化操作并向文件中输出文件头信息最后定义销毁方法用于在关闭应用程序时想文件中输出文件尾信息。 2. 准备配置文件 bean idresourceBean classcn.javass.spring.chapter3.bean.ResourceBean init-methodinit destroy-methoddestroy property namefile valueD:/test.txt/
/bean
bean iddependentBean classcn.javass.spring.chapter3.bean.DependentBean init-methodinit destroy-methoddestroy depends-onresourceBean property nameresourceBean refresourceBean/
/bean property namefile valueD:/test.txt/配置Spring容器能自动把字符串转换为java.io.File。 init-methodinit 指定初始化方法在构造器注入和setter注入完毕后执行。 destroy-methoddestroy指定销毁方法只有“singleton”作用域能销毁“prototype”作用域的一定不能其他作用域不一定能后边再介绍。 在此配置中resourceBean初始化在dependentBean之前被初始化resourceBean销毁会在dependentBean销 毁之后执行。 3. 测试 1 public class MoreDependencyInjectTest { 2 Test 3 public void testDependOn() throws IOException { 4 ClassPathXmlApplicationContext context 5 new ClassPathXmlApplicationContext(chapter3/depends-on.xml); 6 //一点要注册销毁回调否则我们定义的销毁方法不执行 7 context.registerShutdownHook(); 8 DependentBean dependentBean 9 context.getBean(dependentBean, DependentBean.class);
10 dependentBean.write(aaa);
11 }
12 } View Code 测试跟其他测试完全一样只是在此我们一定要注册销毁方法回调否则销毁方法不会执行。如果配置没问题会有如下输出 1 ResourceBean:初始化
2 ResourceBean:加载资源执行一些预操作
3 DependentBean:初始化
4 DependentBean:写资源
5 DependentBean:销毁
6 ResourceBean:销毁
7 ResourceBean:释放资源执行一些清理操作 View Code 三. 自动装配 自动装配就是指由Spring来自动地注入依赖对象无需人工参与。 目前Spring3.0支持“no”、“byName ”、“byType”、“constructor”四种自动装配默认是“no”指不支 持自动装配的其中Spring3.0已不推荐使用之前版本的“autodetect”自动装配推荐使用Java 5支持的 Autowired注解方式代替如果想支持“autodetect”自动装配请将schema改为“spring-beans-2.5.xsd” 或去掉 自动装配的好处是减少构造器注入和setter注入配置减少配置文件的长度。自动装配通过配置bean标签的 “autowire”属性来改变自动装配方式。接下来让我们挨着看下配置的含义。 表示使用默认的自动装配默认的自动装配需要在beans标签中使用default-autowire属性指 定其支持“no”、“byName ”、“byType”、“constructor”四种自动装配如果需要覆盖默认自动装配请 继续往下看 1. no 意思是不支持自动装配必须明确指定依赖。 2. byName 通过设置Bean定义属性autowirebyName意思是根据名字进行自动装配只能用于setter注 入。比如我们有方法“setHelloApi”则“byName”方式Spring容器将查找名字为helloApi的Bean并注入如果找 不到指定的Bean将什么也不注入。 bean idhelloApi classcn.javass.spring.chapter2.helloworld.HelloImpl/
bean idbean classcn.javass.spring.chapter3.bean.HelloApiDecorator autowirebyName/ note:这里的byName的意思是上面的bean idhelloApi必须和HelloApiDecorator类中的依赖类HelloImpl的名字一致private HelloImpl helloApi; 1 public class AutowireBeanTest {
2 Test
3 public void testAutowireByName() throws IOException {
4 ClassPathXmlApplicationContext context
5 new ClassPathXmlApplicationContext(chapter3/autowire-byName.xml);
6 HelloApi helloApi context.getBean(bean, HelloApi.class);
7 helloApi.sayHello();
8 }
9 } View Code 是不是不要配置property了如果一个bean有很多setter注入通过“byName”方式是不是能减少很多 property配置。此处注意了在根据名字注入时将把当前Bean自己排除在外比如“hello”Bean类定义了 “setHello”方法则hello是不能注入到“setHello”的。 3. byType 通过设置Bean定义属性autowirebyType意思是指根据类型注入用于setter注入比如 如果指定自动装配方式为“byType”而“setHelloApi”方法需要注入HelloApi类型数据则Spring容器将查找 HelloApi类型数据如果找到一个则注入该Bean如果找不到将什么也不注入如果找到多个Bean将优先注入 bean标签“primary”属性为true的Bean否则抛出异常来表明有个多个Bean发现但不知道使用哪个。让我们用例 子来讲解一下这几种情况吧。 在根据类型注入时将把当前Bean自己排除在外(note:byType时就不需要helloApi必须和依赖属性名一样了只和类型有关系因此将上面的例子中byName改成byType就可以直接运行了 note: 通过设置Bean定义的“autowire-candidate”属性为false来把指定Bean后自动装配候选者中移除 bean classcn.javass.spring.chapter2.helloworld.HelloImpl autowire-candidatefalse/ 4. constructor 通过设置Bean定义属性autowireconstructor功能和“byType”功能一样根据类 型注入构造器参数只是用于构造器注入方式直接将上面例子的byName改成constructor就好了 5. 全局自动装配 可以采用在“beans”标签中通过“default-autowire”属性指定全局的自动装配方式即如果defaultautowire”byName”将对所有Bean进行根据名字进行自动装配。 6. 不是所有类型都能自动装配 不能自动装配的数据类型Object、基本数据类型Date、CharSequence、Number、URI、URL、Class、int等通过“beans”标签default-autowire-candidates属性指定的匹配模式不匹配的将不能作为自动装配的候选者例如指定“*Service*Dao”将只把匹配这些模式的Bean作为候选者而不匹配的不会作为候选者通过将“bean”标签的autowire-candidate属性可被设为false从而该Bean将不会作为依赖注入的候选者。7. 数组、集合、字典类型的根据类型自动装配和普通类型的自动装配是有区别的 数组类型、集合Set、Collection、List接口类型将根据泛型获取匹配的所有候选者并注入到数组或集合中如“ListHelloApi list”将选择所有的HelloApi类型Bean并注入到list中而对于集合的具体类型将只选择一个候选者“如 ArrayListHelloApi list”将选择一个类型为ArrayList的Bean注入而不是选择所有的HelloApi类型Bean进行注入字典Map接口类型同样根据泛型信息注入键必须为String类型的Bean名字值根据泛型信息获取如“MapString, HelloApi map” 将选择所有的HelloApi类型Bean并注入到map中而对于具体字典类型如“HashMapString, HelloApi map”将只选择类型为HashMap的Bean注入而不是选择所有的HelloApi类型Bean进行注入。8. 自动装配的优缺点 优点首先自动装配确实减少了配置文件的量其次 “byType”自动装配能在相应的Bean更改了字段类型时自动更新即修改Bean类不需要修改配置确实简单了。 缺点最重要的缺点就是没有了配置在查找注入错误时非常麻烦还有比如基本类型没法完成自动装配所以可能经常发生一些莫名其妙的错误在此我推荐大家不要使用该方式最好是指定明确的注入方式或者采用最新的Java5注解注入方式。所以大家在使用自动装配时应该考虑自己负责项目的复杂度来进行衡量是否选择自动装配方式。 自动装配注入方式能和配置注入方式一同工作吗当然可以大家只需记住配置注入的数据会覆盖自动装配注入的数据。 9. 依赖检查 上一节介绍的自动装配很可能发生没有匹配的Bean进行自动装配如果此种情况发生只有在程序运行过程中 发生了空指针异常才能发现错误如果能提前发现该多好啊这就是依赖检查的作用。 依赖检查用于检查Bean定义的属性都注入数据了不管是自动装配的还是配置方式注入的都能检查如果没有注入数 据将报错从而提前发现注入错误只检查具有setter方法的属性。Spring3也不推荐配置方式依赖检查了建议采用Java5 Required注解方式测试时请将XML schema降低为2.5 版本的和自动装配中“autodetect”配置方式的xsd一样。 依赖检查有none、simple、object、all四种方式接下来让我们详细介绍一下 1none 默认方式表示不检查 2objects 检查除基本类型外的依赖对象配置方式为dependency-checkobjects此处我们为 HelloApiDecorator添加一个String类型属性“message”来测试如果有简单数据类型的属性为null也不报错 bean idhelloApi classcn.javass.spring.chapter2.helloworld.HelloImpl/
!-- 注意我们没有注入helloApi所以测试时会报错 --
bean idbean classcn.javass.spring.chapter3.bean.HelloApiDecorator dependency-checkobjects
property namemessage valueHaha/
/bean 注意由于我们没有注入bean需要的依赖“helloApi”所以应该抛出异常UnsatisfiedDependencyException表示没有发现满足的依赖 public class DependencyCheckTest {
Test(expected UnsatisfiedDependencyException.class)
public void testDependencyCheckByObject() throws IOException {
//将抛出异常 new ClassPathXmlApplicationContext(chapter3/dependency-check-object.xml); }
} 3simple 对基本类型进行依赖检查包括数组类型其他依赖不报错配置方式为dependency-checksimple以下配置中没有注入message属性所以会抛出异常 bean idhelloApi classcn.javass.spring.chapter2.helloworld.HelloImpl/
!-- 注意我们没有注入message属性所以测试时会报错 --
bean idbean
classcn.javass.spring.chapter3.bean.HelloApiDecorator dependency-checksimple property namehelloApi refhelloApi/
/bean 4all 对所以类型进行依赖检查配置方式为dependency-checkall如下配置方式中如果两个属性其中一个没配置将报错。 bean idhelloApi classcn.javass.spring.chapter2.helloworld.HelloImpl/
bean idbean
classcn.javass.spring.chapter3.bean.HelloApiDecorator dependency-checkall property namehelloApi refhelloApi/
property namemessage valueHaha/
/bean 依赖检查也可以通过“beans”标签中default-dependency-check属性来指定全局依赖检查配置。 参考文献 https://jinnianshilongnian.iteye.com/blog/1415461 转载于:https://www.cnblogs.com/Hermioner/p/10193125.html