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依赖注入

初识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对象(代码片段