在使用 Spring 框架进行开发时,有时候需要获取 Spring 容器中的 bean 实例或者获取一些环境信息等,在这样的场景下,就需要使用 Spring Aware 接口。
一、BeanNameAware 接口
BeanNameAware 接口能够让 bean 获取自己在 Spring 容器中的 Bean 名称。其接口定义如下:
public interface BeanNameAware {
void setBeanName(String name) throws BeansException;
}
实现该接口的 bean 需要实现 setBeanName 方法,获取到 bean 的名称:
@Component
public class MyBeanNameAware implements BeanNameAware {
private String beanName;
@Override
public void setBeanName(String name) throws BeansException {
this.beanName = name;
}
public void printBeanName() {
System.out.println("Bean Name: " + beanName);
}
}
使用该 bean 时,可以调用 printBeanName 方法获取其名称:
@Autowired
private MyBeanNameAware myBeanNameAware;
@Test
public void testBeanNameAware() {
myBeanNameAware.printBeanName(); // 输出 Bean Name: myBeanNameAware
}
二、BeanFactoryAware 接口
BeanFactoryAware 接口让 bean 获取自己所在的工厂,其接口定义如下:
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
这里的 BeanFactory 是 Spring 框架中定义的一个接口,其实现类是 DefaultListableBeanFactory。通过实现 BeanFactoryAware 接口,可以拿到 bean 所在的 BeanFactory 对象,进而获取更多上下文信息。
@Component
public class MyBeanFactoryAware implements BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void printBeanCount() {
System.out.println("Bean Count: " + beanFactory.getBeanDefinitionCount());
}
}
使用该 bean 时,可以调用 printBeanCount 方法,获取 BeanFactory 中 Bean 的个数:
@Autowired
private MyBeanFactoryAware myBeanFactoryAware;
@Test
public void testBeanFactoryAware() {
myBeanFactoryAware.printBeanCount();
}
三、ApplicationContextAware 接口
ApplicationContextAware 接口让 bean 获取应用上下文的信息,其接口定义如下:
public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
实现该接口的 bean 可以获取应用上下文信息,例如获取其路径等一系列信息。
@Component
public class MyApplicationContextAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void printPath() {
System.out.println("Application Context Path: " + applicationContext.getApplicationName());
}
}
使用该 bean 时,可以调用 printPath 方法获取应用上下文的路径:
@Autowired
private MyApplicationContextAware myApplicationContextAware;
@Test
public void testApplicationContextAware() {
myApplicationContextAware.printPath();
}
四、EnvironmentAware 接口
EnvironmentAware 接口让 bean 获取环境信息,其接口定义如下:
public interface EnvironmentAware {
void setEnvironment(Environment environment);
}
通过实现该接口,可以获取前缀、后缀、属性值等环境信息,下面是一个示例:
@Component
public class MyEnvironmentAware implements EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public void printPrefix() {
System.out.println("Prefix: " + environment.getProperty("spring.prefix"));
}
}
使用该 bean 时,可以调用 printPrefix 方法获取环境变量中的前缀信息:
@Autowired
private MyEnvironmentAware myEnvironmentAware;
@Test
public void testEnvironmentAware() {
myEnvironmentAware.printPrefix();
}
五、ResourceLoaderAware 接口
ResourceLoaderAware 接口让 bean 获取资源加载器,其接口定义如下:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
使用 ResourceLoaderAware 的目的是在 bean 中动态加载类路径下的资源,例如加载配置文件等。下面是一个如何使用 ResourceLoaderAware 获取资源的示例:
@Component
public class MyResourceLoaderAware implements ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void readResource() throws IOException {
Resource resource = resourceLoader.getResource("classpath:test.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
使用该 bean 时,可以调用 readResource 方法获取类路径下的 test.txt 文件内容:
@Autowired
private MyResourceLoaderAware myResourceLoaderAware;
@Test
public void testResourceLoaderAware() throws IOException {
myResourceLoaderAware.readResource();
}