1.概述

在本文中,我们将介绍Spring Framework中的BeanNameAwareBeanFactoryAware接口。

我们会分别介绍每个接口及其用法的优缺点。

2. Aware接口

BeanNameAwareBeanFactoryAware继承自org.springframework.beans.factory.Aware接口。

在应用程序上下文启动期间,使用setter注入将要来获取对象。

**Aware接口是回调,监听器和观察者设计模式的组合。**它指示Spring容器可以通过回调方法来通知是实现该接口的bean。

3. BeanNameAware

BeanNameAware接口是让实现它的对象可以知道Spring容器中定义的bean名称。

我们来看一个例子:

public class BeanName implements BeanNameAware {

    private String beanName;

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
        System.out.println(beanName);
    }

    public String getBeanName() {
        return beanName;
    }
}

setBeanName方法的beanName参数表示在Spring容器中注册该bean名称(ID)。

在我们的实现中,我们打印了Bean名称。

下面,让我们在Spring的配置类中注册这种类型的bean:

@Configuration
public class Config {

    @Bean(name = "customBeanName")
    public BeanName customBeanName() {
        return new BeanName();
    }
    
}

在配置类中,我们使用@Bean(name = "customBeanName")来显示的指定BeanName的bean名称。

下面我们来测试一下:

public class BeanNameAwareTest {
    @Test
    public void test_BeanNameAware(){
        ApplicationContext context
                = new AnnotationConfigApplicationContext(Config.class);

        BeanName beanName = context.getBean(BeanName.class);

        assertEquals("customBeanName", beanName.getBeanName());
    }
}

正如我们期望的那样,控制台输出如下:

customBeanName

如果我们从@Bean注解中删除name = "customBeanName"代码,bean的名称将和方法的名字一致。也是customBeanName

4. BeanFactoryAware

BeanFactoryAware用来向Bean中注入BeanFactory对象。这样我们就可以在Bean中访问创建对象的 BeanFactory

我们来看一个例子:

public class MyBeanFactory implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public String getMyBeanName() {
        BeanName beanName = beanFactory.getBean(BeanName.class);
        System.out.println(beanFactory.isSingleton("customBeanName"));
        return beanName.getBeanName();
    }

}

需要注意的是,在getMyBeanName方法里我们使用BeanFactory来获取Spring容器中的BeanName的对象。

我们还需要在Spring的配置类中注册这个bean:

@Bean
public MyBeanFactory getMyBeanFactory() {
  return new MyBeanFactory();
}

通过借助 setBeanFactory方法,我们将Spring容器中的BeanFactory引用赋值给beanFactory属性

我们来测试一下:

@Test
public void test_BeanFactoryAware(){
  ApplicationContext context
    = new AnnotationConfigApplicationContext(Config.class);
  MyBeanFactory myBeanFactory = context.getBean(MyBeanFactory.class);
  assertEquals("customBeanName", myBeanFactory.getMyBeanName());
}

控制台输出如下:

customBeanName
true

我们使用beanFactory.isSingleton("customBeanName")验证customBeanName是否为单例。

5. 什么时候使用

对于BeanNameAware的常见的使用可能是获取bean名称以进行记录或自动注入。

对于BeanFactoryAware来说,可以通过BeanFactory使用旧版代码中的spring bean。

但是,在大多数情况下,除非真的需要它们,否则应避免使用任何Aware接口。实现这些接口会将代码耦合到Spring框架。

6. 总结

在本文中,我们探讨了BeanNameAwareBeanFactoryAware接口以及如何在实践中使用它们。

最后,往常一样,代码可以在Github上找到。