用花瓣网站上的图片做游戏行吗策划是做什么的
内容概要
Aware
接口赋予了Bean更多自感知的能力,通过实现不同的Aware
接口,Bean可以轻松地获取到Spring容器中的其他资源引用,像ApplicationContext
、BeanFactory
等。
这样不仅增强了Bean的功能,还提高了代码的可维护性和扩展性,从而让Spring的IoC容器变得更加强大和灵活。
核心概念
它能解决什么问题?
在Spring中,Aware
接口是一种标记接口,它本身并没有定义任何方法,但是Spring提供了一系列以Aware
命名的接口,如BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
等。
这些接口定义了一些回调方法,通过这些回调方法,Spring容器在初始化Bean时会将容器中的一些资源、状态、环境信息注入到Bean中,使Bean能够感知到这些信息并据此进行相应的操作。
Aware
接口主要用来解决以下技术问题:
- 依赖注入:Spring的核心功能之一就是依赖注入(DI),但有时候标准的依赖注入方式可能无法满足某些特定的需求。例如,当需要访问当前Bean的名称、BeanFactory或ApplicationContext等信息,通过实现相应的
Aware
接口,可以让Spring容器在初始化Bean时自动将这些信息注入到Bean中。 - 环境感知:有时候,Bean的行为可能需要根据其所处的环境进行调整,例如,在不同的ApplicationContext中,Bean可能需要进行不同的配置或初始化操作,通过实现
ApplicationContextAware
接口,Bean可以访问到当前的ApplicationContext,并据此进行环境感知的操作。 - 资源访问:除了基本的依赖注入和环境感知外,
Aware
接口还可以用于访问Spring容器中的其他资源。例如,通过实现ResourceLoaderAware
接口,Bean可以获得一个ResourceLoader
的引用,用于加载类路径下的资源文件。
它有哪些子类拓展?
以下是Aware
接口的一些常见的子类实现,如下:
- BeanNameAware: 实现此接口的bean可以获得其在Spring容器中的名称,当bean被创建并添加到容器中时,Spring会调用
setBeanName(String name)
方法。 - BeanFactoryAware: 实现此接口的bean可以获得对其所在的
BeanFactory
的引用,这允许bean直接访问容器以查找或操作其他bean,通过setBeanFactory(BeanFactory beanFactory)
方法注入。 - ApplicationContextAware: 与
BeanFactoryAware
类似,但是提供对更高级的ApplicationContext
的访问,实现此接口的bean可以通过setApplicationContext(ApplicationContext context)
方法获得ApplicationContext
的引用。 - MessageSourceAware: 实现此接口的bean可以获得对
MessageSource
的引用,这允许bean进行国际化消息的处理,通过setMessageSource(MessageSource messageSource)
方法注入。 - ApplicationEventPublisherAware: 实现此接口的bean可以获得一个
ApplicationEventPublisher
的引用,用于发布应用事件,Spring会在适当时刻调用setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)
方法。 - ResourceLoaderAware: 实现此接口的bean可以获得对
ResourceLoader
的引用,这使得bean可以加载资源,如配置文件等,通过setResourceLoader(ResourceLoader resourceLoader)
方法注入。 - EnvironmentAware: 实现此接口的bean可以获得对当前应用环境的
Environment
对象的引用。这允许bean查询配置的属性、配置文件等,通过setEnvironment(Environment environment)
方法注入。 - EmbeddedValueResolverAware: 实现此接口的bean可以获得对字符串值解析器的引用,该解析器能够处理占位符(如
${...}
),通过setEmbeddedValueResolver(StringValueResolver resolver)
方法注入。 - SchedulingConfigurerAware (不直接属于
Aware
接口系列, 但类似): 允许配置计划任务,在Spring Boot应用中,可以通过实现SchedulingConfigurer
接口和覆盖configureTasks(ScheduledTaskRegistrar taskRegistrar)
方法来定义计划任务。
代码案例
下面列举举个常见的Aware
子类实现案例。
BeanFactoryAware接口
BeanFactoryAware
接口允许一个bean在初始化时获得对BeanFactory
的引用,这通常用于需要以编程方式访问其他bean或执行与容器相关的操作的场景。下面是一个简单的例子,演示了BeanFactoryAware
接口使用,如下代码:
先创建一个实现了BeanFactoryAware
接口的类:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component; @Component
public class MyBeanFactoryAwareBean implements BeanFactoryAware { private BeanFactory beanFactory; // 实现BeanFactoryAware接口的回调方法 @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } // 一个简单的方法,用于从BeanFactory中获取bean public Object getBean(String beanName) { return beanFactory.getBean(beanName); }
}
然后,创建一个简单的bean,后面将通过MyBeanFactoryAwareBean
来获取它:
import org.springframework.stereotype.Component; @Component
public class MySimpleBean { public String sayHello() { return "Hello from MySimpleBean!"; }
}
接下来,创建一个配置类来启动Spring应用:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan(basePackages = "com.example") // 假设上面的类在com.example包下
public class AppConfig { // 这里不需要额外的bean定义,因为@Component注解已经足够
}
最后,编写一个客户端类来运行应用并测试MyBeanFactoryAwareBean
:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class ClientApp { public static void main(String[] args) { // 创建一个Spring应用上下文 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // 获取MyBeanFactoryAwareBean的实例 MyBeanFactoryAwareBean beanFactoryAwareBean = context.getBean(MyBeanFactoryAwareBean.class); // 使用MyBeanFactoryAwareBean来获取MySimpleBean的实例 MySimpleBean simpleBean = (MySimpleBean) beanFactoryAwareBean.getBean("mySimpleBean"); // 调用MySimpleBean的方法并打印结果 System.out.println(simpleBean.sayHello()); // 关闭应用上下文 ((AnnotationConfigApplicationContext) context).close(); }
}
ApplicationContextAware接口
ApplicationContextAware
接口允许一个bean在初始化时获得对ApplicationContext
的引用,通常用于需要以编程方式访问其他bean或执行与Spring应用上下文相关的操作的场景。
如下代码,演示了如何实现ApplicationContextAware
接口,并在客户端代码中调用该bean。
首先,创建一个实现了ApplicationContextAware
接口的类:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; @Component
public class MyApplicationContextAwareBean implements ApplicationContextAware { private ApplicationContext applicationContext; // 实现ApplicationContextAware接口的回调方法 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } // 一个简单的方法,用于从ApplicationContext中获取bean public Object getBean(String beanName) { return applicationContext.getBean(beanName); }
}
然后,创建一个简单的bean,稍后将通过MyApplicationContextAwareBean
来获取它:
import org.springframework.stereotype.Component; @Component
public class MySimpleBean { public String sayHello() { return "Hello from MySimpleBean!"; }
}
接下来,创建一个配置类来启动Spring应用:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan(basePackages = "com.example") // 假设上面的类在com.example包下
public class AppConfig { // 这里不需要额外的bean定义,因为@Component注解已经足够
}
最后,编写一个客户端类来运行应用并测试MyApplicationContextAwareBean
:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class ClientApp { public static void main(String[] args) { // 创建一个Spring应用上下文 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // 获取MyApplicationContextAwareBean的实例 MyApplicationContextAwareBean contextAwareBean = context.getBean(MyApplicationContextAwareBean.class); // 使用MyApplicationContextAwareBean来获取MySimpleBean的实例 MySimpleBean simpleBean = (MySimpleBean) contextAwareBean.getBean("mySimpleBean"); // 调用MySimpleBean的方法并打印结果 System.out.println(simpleBean.sayHello()); // 关闭应用上下文(尽管在这个例子中不是必须的,因为main方法结束后JVM会退出) ((AnnotationConfigApplicationContext) context).close(); }
}
EnvironmentAware接口
EnvironmentAware
接口允许bean在其初始化之后访问到Environment
属性。
Environment
表示当前应用环境,它封装了应用程序环境的配置属性,例如系统属性、环境变量以及应用上下文中的属性。
如下代码,演示了如何实现Environment
接口。
创建一个类MyEnvironmentAwareBean
实现EnvironmentAware
接口:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.EnvironmentAware;
import org.springframework.context.EnvironmentAwareBean;
import org.springframework.core.env.Environment; public class MyEnvironmentAwareBean implements EnvironmentAware { private Environment environment; // 实现 EnvironmentAware 接口的 setEnvironment 方法 @Override public void setEnvironment(Environment environment) throws BeansException { this.environment = environment; } // 一个简单的方法,用于输出某个属性的值 public void printProperty(String propertyName) { String propertyValue = environment.getProperty(propertyName); System.out.println("Property '" + propertyName + "' = " + propertyValue); }
}
上面的代码中MyEnvironmentAwareBean
类实现了EnvironmentAware
接口,并通过setEnvironment
方法接收Environment
对象。
接下来,配置Spring上下文,注册MyEnvironmentAwareBean
bean,并通过一个客户端类调用它:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class AppConfig { // 声明 MyEnvironmentAwareBean 为一个 bean @Bean public MyEnvironmentAwareBean myEnvironmentAwareBean() { return new MyEnvironmentAwareBean(); }
} public class ClientApp { public static void main(String[] args) { // 创建 AnnotationConfigApplicationContext 上下文 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // 从上下文中获取 MyEnvironmentAwareBean 实例 MyEnvironmentAwareBean myBean = context.getBean(MyEnvironmentAwareBean.class); // 调用 printProperty 方法,打印系统属性 java.version myBean.printProperty("java.version"); // 关闭上下文 context.close(); }
}
ResourceLoaderAware接口
如下代码,演示了如何实现Environment
接口:
创建一个类MyResourceLoaderAwareComponent
实现ResourceLoaderAware
接口,并实现setResourceLoader
方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component; import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner; // 声明这是一个Spring组件
@Component
public class MyResourceLoaderAwareComponent implements ResourceLoaderAware { private ResourceLoader resourceLoader; // 实现了ResourceLoaderAware接口的setResourceLoader方法 @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } // 使用ResourceLoader加载资源并返回资源内容 public String loadResourceContent(String location) { Resource resource = resourceLoader.getResource(location); try (InputStream inputStream = resource.getInputStream(); Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) { StringBuilder content = new StringBuilder(); while (scanner.hasNextLine()) { content.append(scanner.nextLine()).append("\n"); } return content.toString(); } catch (IOException e) { throw new RuntimeException("Failed to load resource: " + location, e); } }
}
创建换一个client类MyResourceLoaderAwareClient
,类中通过@Autowired
将MyResourceLoaderAwareComponent
注入进来,如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class MyResourceLoaderAwareClient { private final MyResourceLoaderAwareComponent myResourceLoaderAwareComponent; @Autowired public MyResourceLoaderAwareClient(MyResourceLoaderAwareComponent myResourceLoaderAwareComponent) { this.myResourceLoaderAwareComponent = myResourceLoaderAwareComponent; } // 客户端方法,用于调用加载资源的方法并打印结果 public void printResourceContent(String location) { String content = myResourceLoaderAwareComponent.loadResourceContent(location); System.out.println("Resource content from location: " + location); System.out.println(content); }
}
最后,Aware
子类比较多,这里就不一一通过代码举例了,但是只需要记住,在Spring中提供的Aware
接口都是为了能够让开发者轻松地获取到Spring容器中的其他资源的引用。
END!
END!
END!
往期回顾
精品文章
Spring揭秘:@import注解应用场景及实现原理!
Java并发基础:原子类之AtomicMarkableReference全面解析!
Java并发基础:concurrent Flow API全面解析
Java并发基础:CopyOnWriteArraySet全面解析
Java并发基础:ConcurrentSkipListMap全面解析