Spring入门(Bean的Aware接口)

来源:互联网 发布:软件版权说明 编辑:程序博客网 时间:2024/05/29 17:14

Aware
Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后,可以获取相应资源。比如BeanNameAware之类的以Aware结尾的接口,这个接口获取的资源就是以BeanName相关的。
通过Aware接口,可以对Spring相应资源进行操作(一定要慎重,因为获取的资源可能是IOC的核心资源)。
为对Spring进行简单的扩展提供了方便的接口。

ApplicationContextAware会向实现了这个接口的Bean提供ApplicationContext,也就是IOC容器的上下文的信息。当然,实现了这个接口的Bean必须配置到bean的配置文件中去,并且由Spring的Bean容器去加载,这样才能实现这样的效果。
BeanNameAware类似,它会提供一个关于BeanName定义的这样一些内容。

接下来是个例子

配置文件

<bean id="moocApplicationContext" class="com.imooc.aware.MoocApplicationContext" ></bean>

实现类

public class MoocApplicationContext implements ApplicationContextAware  {       @Override    public void setApplicationContext(ApplicationContext applicationContext)            throws BeansException {        System.out.println("MoocApplicationContext : " + applicationContext.getBean("moocApplicationContext"));    }   }

测试类

@RunWith(BlockJUnit4ClassRunner.class)public class TestAware extends UnitTestBase {    public TestAware() {        super("classpath:spring-aware.xml");    }    @Test    public void testMoocApplicationContext() {      }}

这个bean我们在配置文件里配置了。
在单元测试类里边调用这个方法(里边没有内容)。这里要注意,在调用这个方法之前会调用Before,之后会调用After。执行这个Before来创建IOC容器,After来销毁。
输出得到MOOCApplicationContext:com.imooc.aware.MoocApplicationContext@156b6b78
在初始化容器的时候调用了setApplicationContext方法,得到了当前这个Bean。

然后可以修改测试类的代码

@Testpublic void testMoocApplicationContext() {    System.out.println("testMoocApplicationContext : " + super.getBean("moocApplicationContext").hashCode());}

看看得到的是不是同一个Bean,我们可以用hashCode来区分是不是同一个。
把实现类中的代码可以稍微修改System.out.println("MoocApplicationContext : " + applicationContext.getBean("moocApplicationContext").hashCode());这里加了一个hashCode。
输出的时候发现哈希值都是一样的,所以得到的是同一个Bean。

也就是说在测试类里边得到的Bean的实例,和Bean定义并实现ApplicationContextAware接口并覆盖它的setApplicationContext方法的时候,从这个applicationContext容器里边得到的Bean的实例是一致的。所以说我们成功的把当前的applicationContext注入到我们的方法中来,或者说成功的写到了类当中来。

这里其实是设值注入。MoocApplicationContext为A,ApplicationContext为B,applicationContext为b。在A类中有SetB的方法,这个方法是Spring的IOC容器自动调用的。给applicationContext也就是属性b进行赋值。
这里和之前写的设置注入有一点不一样。之前会有一个private B b;然后在set方法里会有this.b=b;这是为了在这个类中可以继续使用它。而这个例子里并不需要。重要的并不是有没有那样的赋值操作,而是有没有set方法。