Spring中Bean的命名问题及ref和idref之间的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring中Bean的命名问题及ref和idref之间的区别相关的知识,希望对你有一定的参考价值。

参考技术A

Spring中Bean的命名问题及ref和idref之间的区别

这叫做Spring的依赖注入也叫控制反转。bean的id也就是你说的bean的id,通过id找你想要呼叫的bean,ref不是一个单纯的值,上面那位也说了,ref哪个位置如果你要传字串那就可以用value代替了。 你就可以在你的UserAction中用它了。

一直在用Spring,其实对其了解甚少,刚去了解了一下Spring中Bean的命名问题以及ref和idref之间的区别,略作记录,以备后查。 Spring中Bean的命名 1、每个Bean可以有一个id属性,并可以根据该id在IoC容器中查询该Bean,该id属性值必须在IoC容器中...

Spring中Bean的命名
1、每个Bean可以有一个id属性,并可以根据该id在IoC容器中查询该Bean,该id属性值必须在IoC容器中唯一;
2、可以不指定id属性,只指定全限定类名,如:
<bean class=".zyh.spring3.hello.StaticBeanFactory"></bean>
此时需要通过介面getBean(Class<T> requiredType)来获取Bean;
如果该Bean找不到则抛异常:NoSuchBeanDefinitionException
如果该型别的Bean有多个则抛异常:NoUniqueBeanDefinitionException
3、如果不指定id,只指定name,那么name为Bean的识别符号,并且需要在容器中唯一;
4、同时指定name和id,此时id为识别符号,而name为Bean的别名,两者都可以找到目标Bean;
5、可以指定多个name,之间可以用分号(“;”)、空格(“ ”)或逗号(“,”)分隔开,如果没有指定id,那么第一个name为识别符号,其余的为别名;若指定了id属性,则id为识别符号,所有的name均为别名。如:
<bean name=alias1 alias2;alias3,alias4 id="hello1" class=".zyh.spring3.hello.HelloWorld">
<constructor-arg index="0" value="Rod"></constructor-arg>
</bean>
此时,hello1为识别符号,而alias1,alias2,alias3,alias4为别名,它们都可以作为Bean的键值;
6、可以使用<alias>标签指定别名,别名也必须在IoC容器中唯一,如:
<bean name=bean class=".zyh.spring3.hello.HelloWorld"/>
<alias alias="alias1" name=bean/>
<alias alias="alias2" name=bean/>
ref和idref之间的区别
在Spring中,idref属性和ref属性都可以用在constructor-arg元素和property元素中完成注入,那么它之间有什么区别呢?
考虑如下一段配置:
<bean id="bea" class="java.lang.String">
<constructor-arg index="0"><value>testString</value></constructor-arg>
</bean>
<bean id="beanID" class=".zyh.spring3.hello.HelloWorld">
<constructor-arg name=name><idref bean="bea" /></constructor-arg>
<property name=id>
<ref local="bea" />
</property>
<property name=age value="25"></property>
</bean>
其实,idref注入的是目标bean的id而不是目标bean的例项,同时使用idref容器在部署的时候还会验证这个名称的bean是否真实存在。其实idref就跟value一样,只是将某个字串注入到属性或者建构函式中,只不过注入的是某个Bean定义的id属性值。所以上面的程式码中
<constructor-arg name=name><idref bean="bea" /></constructor-arg>
其实等同于
<constructor-arg name=name><value>bea</value></constructor-arg>
而ref则是完全地不同,ref元素是将目标Bean定义的例项注入到属性或建构函式中,ref元素有三个属性,区别如下:
1、local 只能指定与当前配置的Bean在同一个配置档案中的Bean定义的名称;
2、parent 只能指定位于当前容器的父容器中定义的物件引用;
3、bean 基本上通吃,即包括以上两种情况都可以,所以,通吃情况下,直接使用bean来指定物件引用就可以了。
所以,上面那段配置程式码中,beanID这个Bean中建构函式的引数name注入的只是“bea”这个字串;而其id属性注入的则是testString这个字串。

Spring中Bean的命名 1、每个Bean可以有一个id属性,并可以根据该id在IoC容器中查询... 在Spring中,idref属性和ref属性都可以用在constructor

Spring学习笔记——02 Bean的命名及实例化

一、Bean的命名

前一篇讲到IoC是一个管理Bean的容器,Bean多数情况下都是通过XML文件进行配置的,其中Bean的命名有以下几种方式,现在梳理一下。

1. 不指定id,只配置类名

<bean class="com.erving.HelloImpl"></bean>

若要调用该Bean,需要用以下语句:

HelloApi helloApi = context.getBean(HelloApi.class);

2. 指定id,且id必须在IoC容器中唯一

<bean id="hello" class="com.erving.HelloImpl"></bean>

若要调用,则需要用以下语句:

HelloApi helloApi = context.getBean("hello", HelloApi.class);

3. 指定name,且name必须在IoC容器中唯一

<bean name="hello" class="com.erving.HelloImpl"></bean>

若要调用,则需要用以下语句:

HelloApi helloApi = context.getBean("hello", HelloApi.class);

4. 同时指定了id和name,则id作为标识符,name作为别名,这两者在容器中都唯一。

<bean id="hello" name="alias" class="com.erving.HelloImpl"></bean>

这时Bean即可通过id实例化,也可通过name实例化:

HelloApi helloApi1 = context.getBean("hello", HelloApi.class);
HelloApi helloApi2 = context.getBean("alias", HelloApi.class);

5. 当一个Bean有多个name时,第一个为标识符,其他的为别名。多个name之间可通过分号、顿号或空格隔开。

6. 此外,还可以通过<alias>标签指定别名。

<bean name="hello" class="com.erving.HelloImpl"></bean>
<alias name="hello" alias="alias"/>

这与以下语句的效果完全一致

<bean name="hello;alias" class="com.erving.HelloImpl"></bean>

 

二、Bean的实例化

Bean的实例化有三种形式,分别为构造器、静态工厂和实例工厂。

1. 构造器。

通常情况,通过反射调用指定类的构造器来创建bean。此时bean的类型不一定为JavaBean,任何Java类都可以。构造器又分为无参数构造器和有参数构造器。

以上介绍的都是无参数构造器,配置如下:

<bean id="hello" class="com.erving.HelloImpl"></bean>

有参数的构造器,配置如下:

<bean name="hello" class="com.erving.HelloImpl2">
     <constructor-arg index="0" value="erving..."></constructor-arg>
</bean>

2. 静态工厂。

首先定义静态工厂类:

public class HelloApiStaticFactory {
    
    public static HelloApi newInstance(String message) {
        return new HelloImpl2(message);
    }
}

然后编辑配置文件:

<bean id="bean2" class="com.erving.HelloApiStaticFactory" factory-method="newInstance">
      <constructor-arg index="0" value="tian..."></constructor-arg>
</bean>

其中的class属性为静态工厂类,另外需要指明实例化bean的方法。

具体实例化与第一种方法完全一致:

public void testStaticFactory() {
    ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
    HelloApi helloApi = context.getBean("bean2", HelloApi.class);
    helloApi.sayHello();
}

3. 实例工厂。

首先定义实例工厂类:

public class HelloApiInstanceFactory {
    
    public HelloApi newInstance(String message) {
        return new HelloImpl2(message);
    }
}

然后修改配置文件,配置文件分为两部分:一是实例工厂的bean,二是通过工厂bean创建bean。

<!-- 1、定义实例工厂Bean -->  
<bean id="beanInstanceFactory" class="com.erving.HelloApiInstanceFactory"/>  
<!-- 2、使用实例工厂Bean创建Bean -->  
<bean id="bean4" factory-bean="beanInstanceFactory" factory-method="newInstance">  
    <constructor-arg index="0" value="Hello Spring!"></constructor-arg>  
</bean>

 

以上是关于Spring中Bean的命名问题及ref和idref之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

Spring中Bean的命名问题及ref和idref之间的区别

Spring学习笔记——02 Bean的命名及实例化

spring中@autoWired和@Resource的作用及区别

spring之p命名空间注入

Spring框架的补充

Spring bean中的properties元素内的name 和 ref都代表什么意思啊?