Spring04-----DI
Posted Hermioner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring04-----DI相关的知识,希望对你有一定的参考价值。
一. Bean的命名
每个Bean可以有一个或多个id(或称之为标识符或名字),在这里我们把第一个id称为“标识符”,其余id叫做 “别名”;这些id在IoC容器中必须唯一。如何为Bean指定id呢,有以下几种方式;
1. 不指定id,只配置必须的全限定类名,由IoC容器为其生成一个标识,客户端必须通过接口“T getBean(Class<T> requiredType)”获取Bean
<bean class=” cn.javass.spring.chapter2.helloworld.HelloImpl”/> (1)
@Test public void test1() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter2/namingbean1.xml"); //根据类型获取bean HelloApi helloApi = beanFactory.getBean(HelloApi.class); helloApi.sayHello(); }
2. 指定id,必须再Ioc容器中唯一;
<bean id=” bean” class=” cn.javass.spring.chapter2.helloworld.HelloImpl”/> (2)
@Test public void test2() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter2/namingbean2.xml"); //根据id获取bean HelloApi bean = beanFactory.getBean("bean", HelloApi.class); bean.sayHello(); }
3. 指定name,这样name就是“标识符”,必须在IOC容器中唯一;
<bean name=” bean” class=” cn.javass.spring.chapter2.helloworld.HelloImpl”/> (3)
@Test public void test3() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter2/namingbean3.xml"); //根据name获取bean HelloApi bean = beanFactory.getBean("bean", HelloApi.class); bean.sayHello(); }
4. 指定id和name,id就是标识符,而name就是别名,必须在Ioc容器中唯一;
<bean id=”bean1”name=”alias1” class=” cn.javass.spring.chapter2.helloworld.HelloImpl”/> <!-- 如果id和name一样,IoC容器能检测到,并消除冲突 --> <bean id="bean3" name="bean3" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/> (4)
@Test public void test4() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter2/namingbean4.xml"); //根据id获取bean HelloApi bean1 = beanFactory.getBean("bean1", HelloApi.class); bean1.sayHello(); //根据别名获取bean HelloApi bean2 = beanFactory.getBean("alias1", HelloApi.class); bean2.sayHello(); //根据id获取bean HelloApi bean3 = beanFactory.getBean("bean3", HelloApi.class); bean3.sayHello(); String[] bean3Alias = beanFactory.getAliases("bean3"); //因此别名不能和id一样,如果一样则由IoC容器负责消除冲突 Assert.assertEquals(0, bean3Alias.length); }
5. 指定多个name,多个name用“,”、“;”、“ ”分割,第一个被用作标识符,其他的(alias1、alias2、 alias3)是别名,所有标识符也必须在Ioc容器中唯一;
<bean name=” bean1;alias11,alias12;alias13 alias14” class=” cn.javass.spring.chapter2.helloworld.HelloImpl”/> <!-- 当指定id时,name指定的标识符全部为别名 --> <bean id="bean2" name="alias21;alias22" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/> (5)
@Test public void test5() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter2/namingbean5.xml"); //1根据id获取bean HelloApi bean1 = beanFactory.getBean("bean1", HelloApi.class); bean1.sayHello(); //2根据别名获取bean HelloApi alias11 = beanFactory.getBean("alias11", HelloApi.class); alias11.sayHello(); //3验证确实是四个别名 String[] bean1Alias = beanFactory.getAliases("bean1"); System.out.println("=======namingbean5.xml bean1 别名========"); for(String alias : bean1Alias) { System.out.println(alias); } Assert.assertEquals(4, bean1Alias.length); //根据id获取bean HelloApi bean2 = beanFactory.getBean("bean2", HelloApi.class); bean2.sayHello(); //2根据别名获取bean HelloApi alias21 = beanFactory.getBean("alias21", HelloApi.class); alias21.sayHello(); //验证确实是两个别名 String[] bean2Alias = beanFactory.getAliases("bean2"); System.out.println("=======namingbean5.xml bean2 别名========"); for(String alias : bean2Alias) { System.out.println(alias); } Assert.assertEquals(2, bean2Alias.length); 31. }
6. 使用<alias>标签指定别名,别名也必须在IoC容器中唯一
<bean name="bean" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/> <alias alias="alias1" name="bean"/>
<alias alias="alias2" name="bean"/> (6)
id和name:
从定义来看,name或id如果指定它们中的一个时都作为“标识符”,那为什么还要有id和name同时存在呢?这是因为 当使用基于XML的配置元数据时,在XML中id是一个真正的XML id属性,因此当其他的定义来引用这个id时就体现出id 的好处了,可以利用XML解析器来验证引用的这个id是否存在,从而更早的发现是否引用了一个不存在的bean,而使 用name,则可能要在真正使用bean时才能发现引用一个不存在的bean。
Bean命名约定:Bean的命名遵循XML命名规范,但最好符合Java命名规范,由“字母、数字、下划线组成“,而且 应该养成一个良好的命名习惯, 比如采用“驼峰式”,即第一个单词首字母开始,从第二个单词开始首字母大写开始, 这样可以增加可读性。
二. <beans>和<bean>
所有注册到容器的业务对象,在Spring中称之为Bean。所以,每一个对象在XML中的映射也自然 而然地对应一个叫做<bean>的元素。既然容器终可以管理所有的业务对象,那么在XML中把这些 叫做<bean>的元素组织起来的,就叫做<beans>。多个<bean>组成一个<beans>很容易理解。
<beans>作为所有<bean>的“统帅”,它拥有相应的属性(attribute)对所辖的<bean>进行统一 的默认行为设置,包括如下几个
- default-lazy-init。其值可以指定为true或者false,默认值为false。用来标志是否对所 有的<bean>进行延迟初始化。
- default-autowire。可以取值为no、byName、byType、constructor以及autodetect。默 认值为no,如果使用自动绑定的话,用来标志全体bean使用哪一种默认绑定方式。
- default-dependency-check。可以取值none、objects、simple以及all,默认值为none, 即不做依赖检查。
- default-init-method。如果所管辖的<bean>按照某种规则,都有同样名称的初始化方法的 话,可以在这里统一指定这个初始化方法名,而不用在每一个<bean>上都重复单独指定。
- default-destroy-method。与default-init-method相对应,如果所管辖的bean有按照某种 规则使用了相同名称的对象销毁方法,可以通过这个属性统一指定。
Note:
在bean.xml中配置的时候一定要让class是具体实现类,否则该bean对象无法完成实例化。会报错。因为具体实例化的时候是根据这里的地址进行实例化处理的。
参考文献:
《spring揭秘》
参考文献:
http://jinnianshilongnian.iteye.com
以上是关于Spring04-----DI的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
Spring boot:thymeleaf 没有正确渲染片段
What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段