7.8.4 获得Bean本身的id

7.8.4 获得Bean本身的id

对于实际的Java应用而言,BeanBean之间的关系是通过依赖注入管理的,通常不会通过调用容器的getBean()方法来获取Bean实例。可能的情况是,应用中已经获得了Bean实例的引用,但程序无法知道配置该Bean时指定的id,可是程序又确实需要获取配置该Bean时指定的id属性
此外,当程序员在开发一个Bean类时,该Bean何时被部署到Spring容器中,部署到Spring容器时所指定的id是什么,开发该Bean类的程序员无法提前预知.
在某些极端情况下,业务要求程序员在开发Bean类时能预先知道该Bean的配置id,此时可借Spring提供的BeanNameAware接口,通过BeanNameAware接口即可提前预知该Bean的配置id
BeanNameAware接口提供了一个方法:

方法 描述
setName(String name) 该方法的name参数就是Beanid,实现该方法的Bean类就可通过该方法来获得部署该Beanid

BeanNameAware接口中的setBeanName(String name)方法与前面介绍的BeanFactoryAwareApplicationContextAware两个接口中的setter方法一样,这个setter方法不是由程序员来调用的,该方法由Spring容器负责调用—当Spring容器调用这个setter方法时,会把部署该Beanid属性作为参数传入。

程序示例

项目结构

1
2
3
4
5
6
7
8
9
10
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\BeanNameAware
└─src\
├─beans.xml
├─lee\
│ └─SpringTest.java
└─org\
└─crazyit\
└─app\
└─service\
└─Chinese.java

Chinese.java

下面定义了一个Bean,该Bean实现了BeanNameAware接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.crazyit.app.service;

import org.springframework.beans.factory.BeanNameAware;

public class Chinese implements BeanNameAware
{
// 保存部署该Bean时指定的id属性
private String beanName;
// Spring容器会在创建该Bean之后,自动调用它的setBeanName()方法,
// 调用该方法时,会将该Bean的配置id作为参数传给该方法
public void setBeanName(String name)
{
this.beanName = name;
}
public void info()
{
System.out.println("Chinese实现类" + ", 部署该Bean时指定的id为" + beanName);
}
}

上面的Chinese类实现了BeanNameAware接口,并实现了该接口提供的setBeanName()方法。

beans.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Spring容器会检测容器中所有Bean,如果发现某个Bean实现了BeanNameAware接口,
Spring容器会在创建该Bean之后,自动调用该Bean的setBeanName()方法,
调用该方法时,会将该Bean的配置id作为参数传给该方法
该方法的实现部分将Spring传入的参数(Bean的配置id)赋为给该Chinese对象的
beanName实例变量,因此接下来即可通过该beanName实例变量来访问Bean的配置id。-->
<bean id="chinese" class="org.crazyit.app.service.Chinese"/>
</beans>

Spring容器会检测容器中的所有Bean,如果发现某个Bean实现了BeanNameAware接口, Spring容器就会在创建该Bean之后,自动调用该BeansetBeanName()方法,调用该方法时,会将该Bean的配置id作为参数传给该方法—该方法的实现部分将Spring传入的参数(Bean的配置id)赋给该Chinese对象的beanName实例变量,因此接下来即可通过该beanName实例变量来访问Bean的配置id.

SpringTest.java

将该Bean部署在容器中,该Bean的部署与普通Bean的部署没有任何区别。在主程序中通过如下代码测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package lee;

import org.springframework.context.*;
import org.springframework.context.support.*;

import org.crazyit.app.service.*;

public class SpringTest
{
public static void main(String[] args)
{
// 创建Spring容器,容器会自动预初始化所有singleton Bean实例
@SuppressWarnings("resource")
ApplicationContext ctx =
new ClassPathXmlApplicationContext("beans.xml");
Chinese chin = ctx.getBean("chinese" , Chinese.class);
chin.info();
}
}

执行结果

1
Chinese实现类, 部署该Bean时指定的id为chinese

从代码执行结果可以看到, Spring容器初始化Chinese这个Bean时回调setBeanName()方法,回调该方法时,该Bean的配置id将会作为参数传给beanName实例变量,这样该Bean的其他方法即可通过beanName实例变量来访问该Bean的配置id

小结

Bean类中需要获得Bean的配置id的情形并不是特别常见的,但如果有这种需即可考虑让Bean类实现BeanNameAware接口。