📫作者简介:​​zhz小白​​ 公众号:​小白的Java进阶之路​​
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等

本人著作git项目:​​​https://gitee.com/zhouzhz/star-jersey-platform​​​
领域:​​对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域​​

文章目录

  • ​​1、整体Aware接口图谱​​
  • ​​2、Aware在工作中如何使用?​​
  • ​​2.1、ApplicationContextAware(常用)​​
  • ​​2.1.1、使用例子​​
  • ​​2.2、BeanClassLoadAware(常用)​​
  • ​​2.2.1、使用例子​​
  • ​​2.3、ApplicationEventPublisherAware(常用)​​
  • ​​2.3.1、使用例子​​
  • ​​2.3.1.1、pojo​​
  • ​​2.3.1.2、controller​​
  • ​​2.3.1.3、service​​
  • ​​2.3.1.4、listener​​
  • ​​2.3.1.5、event​​
  • ​​2.3.1.6、执行过程​​
  • ​​2.3.2、扩展​​
  • ​​2.3.2.1、@TransactionalEventListener 监听器​​
  • ​​2.3.2.2、可以在监听器中重新开一个事务​​
  • ​​2.4、LoadTimeWeaverAware​​
  • ​​2.4.1、使用例子​​
  • ​​2.5、MessageSourceAware(常用)​​
  • ​​2.5.1、使用例子​​
  • ​​2.6、ImportAware​​
  • ​​2.6.1、使用例子​​
  • ​​2.7、EnvironmemtAware(常用)​​
  • ​​2.7.1、研发背景​​
  • ​​2.7.2、源码介绍以及使用方法​​
  • ​​2.7.3、作用​​
  • ​​2.7.4、使用方式代码示例​​
  • ​​2.7.5、总结​​
  • ​​2.8、BeanFoctoryAware(常用)​​
  • ​​2.8.1、使用例子​​
  • ​​2.9、BeanNameAware(常用)​​
  • ​​2.9.1、使用例子​​
  • ​​2.10、EmbeddedValueResolverAware(常用)​​
  • ​​2.10.1、使用例子​​
  • ​​2.11、ResourceLoaderAware(常用)​​
  • ​​2.11.1、在springboot中使用示例​​
  • ​​3、Aware接口源码​​
  • ​​参考​​

前面的BeanPostProcessor章节中,我们是不是讲了XXXAware接口,是不是很好奇他们各自有什么用呢,并且各自在底层中Spring是怎么实现的呢?下面让我来一一为大家讲解。

1、整体Aware接口图谱

这个图上的基本都是Aware接口的常用实现类,下面让我来给大家一个一个的介绍

【Spring【IOC】】——18、自定义组件中如何注入Spring底层的组件?_后端

2、Aware在工作中如何使用?

2.1、ApplicationContextAware(常用)

  • 获取容器本身ApplicationContext对象,可以在bean中得到bean所在的应用上下文
  • 一般用于获取ApplicationContext对象,大家可以看一下里面的方法,其源码如下:

    他能做的事情,方法汇总

2.1.1、使用例子

package com.zhz.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
* @description: Spring应用上下文工具类
* @motto: 代码源于生活,高于生活艺术
* @author: zhouhengzhe
* @date: 2022/12/8 18:58
* @since 1.0
**/
@Component
public class SpringApplicationContextHolder implements ApplicationContextAware {

private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringApplicationContextHolder.applicationContext = applicationContext;
}

public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return applicationContext.getBean(clazz);
}

private static void checkApplicationContext() {
if (Objects.isNull(applicationContext)) {
throw new RuntimeException("未注入ApplicationContext,请注入");
}
}
}

假设我们有一个BookService类需要用到BookDao类,如下

package com.zhz.service;

import com.zhz.dao.BookDao;
import com.zhz.utils.SpringApplicationContextHolder;
import org.springframework.stereotype.Service;

/**
* @author zhouhengzhe
* @description: todo
* @date 2022/11/4 10:56
* @since v1
*/
@Service
public class BookService {
public void sout(){
BookDao bean = SpringApplicationContextHolder.getBean(BookDao.class);
System.out.println(bean);
}
}

接着我们运行一下测试类

@Test
public void test2(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
BookService bean = applicationContext.getBean(BookService.class);
System.out.println(bean);
}

【Spring【IOC】】——18、自定义组件中如何注入Spring底层的组件?_使用例子_02

2.2、BeanClassLoadAware(常用)

  • 获取加载当前bean的类加载器
  • BeanClassLoaderAware的作用是让受管Bean本身知道它是由哪一类装载器负责装载的。

2.2.1、使用例子

代码示例来源:​​origin: spring-projects/spring-framework​

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

代码示例来源:​​origin: org.springframework/spring-beans​

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

代码示例来源:​​origin: spring-projects/spring-framework​

/**
* Invoke {@link BeanClassLoaderAware}, {@link BeanFactoryAware},
* {@link EnvironmentAware}, and {@link ResourceLoaderAware} contracts
* if implemented by the given object.
*/
public static void invokeAwareMethods(Object parserStrategyBean, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
if (parserStrategyBean instanceof Aware) {
if (parserStrategyBean instanceof BeanClassLoaderAware) {
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
if (classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
}
if (parserStrategyBean instanceof EnvironmentAware) {
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
}
if (parserStrategyBean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
}
}
}

代码示例来源:​​origin: org.springframework/spring-context​

/**
* Invoke {@link BeanClassLoaderAware}, {@link BeanFactoryAware},
* {@link EnvironmentAware}, and {@link ResourceLoaderAware} contracts
* if implemented by the given object.
*/
public static void invokeAwareMethods(Object parserStrategyBean, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
if (parserStrategyBean instanceof Aware) {
if (parserStrategyBean instanceof BeanClassLoaderAware) {
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
if (classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
}
if (parserStrategyBean instanceof EnvironmentAware) {
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
}
if (parserStrategyBean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
}
}
}

代码示例来源:​​origin: spring-projects/spring-security​

@Test
public void postProcessWhenBeanClassLoaderAwareThenAwareInvoked() {
this.spring.register(Config.class).autowire();
BeanClassLoaderAware toPostProcess = mock(BeanClassLoaderAware.class);
this.objectObjectPostProcessor.postProcess(toPostProcess);
verify(toPostProcess).setBeanClassLoader(isNotNull());
}

代码示例来源:​​origin: spring-projects/spring-integration​

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
if (this.jsonObjectMapper instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) this.jsonObjectMapper).setBeanClassLoader(classLoader);
}
}

代码示例来源:​​origin: spring-projects/spring-framework​

((BeanClassLoaderAware) pfb.getHttpInvokerRequestExecutor()).setBeanClassLoader(getClass().getClassLoader());

代码示例来源:​​origin: camunda/camunda-bpm-platform​

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

代码示例来源:​​origin: spring-projects/spring-integration​

private static void invokeAwareMethods(Object parserStrategyBean, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
if (parserStrategyBean instanceof Aware) {
if (parserStrategyBean instanceof BeanClassLoaderAware) {
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
if (classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
}
if (parserStrategyBean instanceof EnvironmentAware) {
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
}
if (parserStrategyBean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
}
}
}

代码示例来源:​​origin: org.springframework.integration/spring-integration-core​

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
if (this.jsonObjectMapper instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) this.jsonObjectMapper).setBeanClassLoader(classLoader);
}
}

代码示例来源:​​origin: org.apache.james/james-server-lifecycle-spring​

static void setBeanClassLoader(Object importer, ClassLoader cl) {
((BeanClassLoaderAware) importer).setBeanClassLoader(cl);
}

代码示例来源:​​origin: org.eclipse.gemini.blueprint/gemini-blueprint-extensions​

static void setBeanClassLoader(Object importer, ClassLoader cl) {
((BeanClassLoaderAware) importer).setBeanClassLoader(cl);
}

代码示例来源:​​origin: apache/servicemix-bundles​

private void forwardBeanClassLoader(BeanClassLoaderAware target) {
if (beanClassLoader != null) {
target.setBeanClassLoader(beanClassLoader);
}
}

代码示例来源:​​origin: org.springframework.osgi/spring-osgi-annotation​

static void setBeanClassLoader(Object importer, ClassLoader cl) {
((BeanClassLoaderAware) importer).setBeanClassLoader(cl);
}

代码示例来源:​​origin: spring-projects/spring-integration​

((BeanClassLoaderAware) bean).setBeanClassLoader(this.beanFactory.getBeanClassLoader()); // NOSONAR

代码示例来源:​​origin: apache/servicemix-bundles​

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

代码示例来源:​​origin: org.springframework.osgi/org.springframework.osgi.extender​

public void postProcessBeanFactory(BundleContext bundleContext, ConfigurableListableBeanFactory beanFactory)
throws BeansException, OsgiException {
Bundle bundle = bundleContext.getBundle();
try {
// Try and load the annotation code using the bundle classloader
Class annotationBppClass = bundle.loadClass(ANNOTATION_BPP_CLASS);
// instantiate the class
final BeanPostProcessor annotationBeanPostProcessor = (BeanPostProcessor) BeanUtils.instantiateClass(annotationBppClass);
// everything went okay so configure the BPP and add it to the BF
((BeanFactoryAware) annotationBeanPostProcessor).setBeanFactory(beanFactory);
((BeanClassLoaderAware) annotationBeanPostProcessor).setBeanClassLoader(beanFactory.getBeanClassLoader());
((BundleContextAware) annotationBeanPostProcessor).setBundleContext(bundleContext);
beanFactory.addBeanPostProcessor(annotationBeanPostProcessor);
}
catch (ClassNotFoundException exception) {
log.info("Spring-DM annotation package could not be loaded from bundle ["
+ OsgiStringUtils.nullSafeNameAndSymName(bundle) + "]; annotation processing disabled...");
if (log.isDebugEnabled())
log.debug("Cannot load annotation injection processor", exception);
}
}
}

代码示例来源:​​origin: org.eclipse.gemini.blueprint/gemini-blueprint-extender​

public void postProcessBeanFactory(BundleContext bundleContext, ConfigurableListableBeanFactory beanFactory)
throws BeansException, OsgiException {
Bundle bundle = bundleContext.getBundle();
try {
// Try and load the annotation code using the bundle classloader
Class<?> annotationBppClass = bundle.loadClass(ANNOTATION_BPP_CLASS);
// instantiate the class
final BeanPostProcessor annotationBeanPostProcessor = (BeanPostProcessor) BeanUtils.instantiateClass(annotationBppClass);
// everything went okay so configure the BPP and add it to the BF
((BeanFactoryAware) annotationBeanPostProcessor).setBeanFactory(beanFactory);
((BeanClassLoaderAware) annotationBeanPostProcessor).setBeanClassLoader(beanFactory.getBeanClassLoader());
((BundleContextAware) annotationBeanPostProcessor).setBundleContext(bundleContext);
beanFactory.addBeanPostProcessor(annotationBeanPostProcessor);
}
catch (ClassNotFoundException exception) {
log.info("Spring-DM annotation package could not be loaded from bundle ["
+ OsgiStringUtils.nullSafeNameAndSymName(bundle) + "]; annotation processing disabled...");
if (log.isDebugEnabled())
log.debug("Cannot load annotation injection processor", exception);
}
}
}

代码示例来源:​​origin: org.springframework.integration/spring-integration-core​

private static void invokeAwareMethods(Object parserStrategyBean, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
if (parserStrategyBean instanceof Aware) {
if (parserStrategyBean instanceof BeanClassLoaderAware) {
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
if (classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
}
if (parserStrategyBean instanceof EnvironmentAware) {
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
}
if (parserStrategyBean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
}
}
}

代码示例来源:​​origin: pl.edu.icm.synat/synat-platform-connector​

@Override
protected <T> T createService(ConnectionDescriptor connectionDescriptor, Class<T> serviceInterface, String serviceId, boolean stateful) {
final HttpInvokerProxyFactoryBean proxyFactoryBean = new HttpInvokerProxyFactoryBean();
proxyFactoryBean.setServiceInterface(serviceInterface);
proxyFactoryBean.setServiceUrl(connectionDescriptor.getLocation().toString());
final HttpInvokerRequestExecutor executor;
final HttpClient httpClient = createHttpClient();
if (stateful) {
executor = new SessionInvokerRequestExecutor(httpClient, serviceSecurityContext, requestConfig);
} else {
executor = new DefaultHttpInvokerRequestExecutor(httpClient, serviceSecurityContext, requestConfig);
}
if (executor instanceof BeanClassLoaderAware) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
((BeanClassLoaderAware) executor).setBeanClassLoader(classLoader);
}
proxyFactoryBean.setHttpInvokerRequestExecutor(executor);
proxyFactoryBean.afterPropertiesSet();
@SuppressWarnings("unchecked")
final T service = clientInterceptorUtil.addHttpInterceptors((T) proxyFactoryBean.getObject(), connectionDescriptor);
return service;
}

2.3、ApplicationEventPublisherAware(常用)

  • 事件发布器的接口,使用这个接口,我们自己的bean就拥有了发布事件的能力。
  • 监听器可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,发送邮件或短信,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发送邮件或短信的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。

2.3.1、使用例子

2.3.1.1、pojo

package com.zhz.bean;

import lombok.*;

/**
* @author zhouhengzhe
* @date 2022/12/13
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class User {
private Integer id;
private String name;
private String phoneNum;
private String email;
}

2.3.1.2、controller

@RestController
@RequestMapping("/user")
public class UserRegisterController {
@Autowired
private UserRegisterService userRegisterService;
@RequestMapping("/register")
public String register(User user) {
//进行注册
userRegisterService.register(user);
return "[controller]注册用户成功!";

}
}

2.3.1.3、service

@Service
public class UserRegisterService implements ApplicationEventPublisherAware {

private ApplicationEventPublisher applicationEventPublisher;

public boolean register(User user) {

//用户注册
System.out.println("[service]用户[" + user + "]注册成功!");

//消息发布
applicationEventPublisher.publishEvent(new UserRegisterEvent(this, user));

return true;
}

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;

}
}

2.3.1.4、listener

@Component
public class EventListener implements ApplicationListener<UserRegisterEvent> {

@Override
public void onApplicationEvent(UserRegisterEvent event) {

//发邮件
System.out.println("正在发送邮件至: " + event.getUser().getEmail());

//发短信
System.out.println("正在发短信到: " + event.getUser().getPhoneNum());
}
}

可以使用注解
@EventListener
使用在类上表示是监听方法(未验证)

//监听事件
@EventListener
public void listenEvent(UserRegisterEvent event) {
//发邮件
System.out.println("正在发送邮件至: " + event.getUser().getEmail());

//发短信
System.out.println("正在发短信到: " + event.getUser().getPhoneNum());
}

2.3.1.5、event

@Getter
public class UserRegisterEvent extends ApplicationEvent {
private static final long serialVersionUID = -5481658020206295565L;
private User user;
//谁发布的这个事件,souce就是谁(对象)
public UserRegisterEvent(Object source, User user) {
super(source);
this.user = user;
}
}

2.3.1.6、执行过程

  • controller层调用service中的注册方法触发监听事件,并创建这个事件类(内部可做其他操作),然后.publishEvent发布事件。监听这个事件类的监听器就会监听到这个事件,然后onApplicationEvent执行内部方法。

2.3.2、扩展

2.3.2.1、@TransactionalEventListener 监听器

  • 如果事件的发布不是在事务(@Transactional)范围内,则监听不到该事件,除非将fallbackExecution标志设置为true(@TransactionalEventListener(fallbackExecution = true));如果在事务中,可以选择在事务的哪个阶段来监听事件,默认在事务提交后监听。
修改监听事务的范围:@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)

2.3.2.2、可以在监听器中重新开一个事务

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
public void listenEvent1(UserRegisterEvent event) {
divide(event);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void divide(UserRegisterEvent event) {
//发邮件
System.out.println("正在发送邮件至: " + event.getUser().getEmail());

//发短信
System.out.println("正在发短信到: " + event.getUser().getPhoneNum());
}

2.4、LoadTimeWeaverAware

  • 可获取LoadTimeWeaver实例,用于在加载时处理类定义

2.4.1、使用例子

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有的(非懒加载的)单实例bean
beanFactory.preInstantiateSingletons();
}

2.5、MessageSourceAware(常用)

  • 国际化处理相关
  • 项目启动时不同环境加载不同的配置。

2.5.1、使用例子

2.6、ImportAware

  • 用来处理自定义注解的,比如将注解里面的某些属性值赋值给其他Bean
  • ImportAware也是要配合@Import()注解一起使用

2.6.1、使用例子

2.7、EnvironmemtAware(常用)

  • 可以获取到系统的环境变量信息

2.7.1、研发背景

我們在搞新的配置中心Nacos的時候,为了获取新的配置中心的配置文件中配置的 dataId,以及配置 serverAddr、nacosGroup 等信息,所以才研究 EnvironmentAware 接口的如果写死话那岂不是太不像话了,那就太多的魔法值了,所以我们可以通过 environmentAware 这个接口进行从配置文件中【application.properties】获取配置的配置中心的信息详情。
nacos.config.server-addr=IP地址
nacos.config.data-id=api.properties
nacos.config.group=DEFAULT_GROUP
nacos.config.namespace=public
nacos.config.username=nacos
nacos.config.password=nacos
nacos.config.auto-refresh=true
nacos.config.type=properties
nacos.config.bootstrap.enable=true
nacos.config.bootstrap.log-enable=true

2.7.2、源码介绍以及使用方法

  • 其实说白了就是哪个接口需要获取配置,那么那个接口就需要进行实现该接口 EnvironmentAware并实现里面的 setEnvironment方法
/**
其实说白了就是哪个接口需要获取配置,那么那个接口就需要进行实现该接口并实现里面的set方法
*/
public interface EnvironmentAware extends Aware {

void setEnvironment(Environment environment);

}

2.7.3、作用

  • 所有注册到 Spring容器内的 bean,只要该bean 实现了 EnvironmentAware接口,并且进行重写了setEnvironment方法的情况下,那么在工程启动时就可以获取得 application.properties 的配置文件配置的属性值,这样就不用我们将魔法值写到代码里面了

2.7.4、使用方式代码示例

  • 通过 NacosController 实现了 EnvironmentAware 这个接口,并且实现了 setEnvironment 方法,之后通过 environment 这个对象进行配置信息获取
@RestController
@RequestMapping("/nacos")
public class NacosController implements EnvironmentAware {

private final static String NACOS_DATA_ID = "nacos.config.data-id";
private final static String NACOS_GROUP = "nacos.config.group";

private static String dataId = "";
private static String group = "";

@NacosInjected
private ConfigService configService;

@Autowired
private Environment environment;

@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
// 通过 environment 获取配置信息
@PostConstruct
private void init() {
dataId = environment.getProperty(NACOS_DATA_ID);
group = environment.getProperty(NACOS_GROUP);
}

/**
* 发布配置
* @return
*/
@RequestMapping(value = "/publishConfig",method = RequestMethod.GET)
public boolean publishConfig() {
boolean res = false;
try {
res = configService.publishConfig(dataId, group, "发布配置");
} catch (NacosException e) {
e.printStackTrace();
}
System.out.println(res);
return res;
}
}

2.7.5、总结

  • 哪个类需要获取配置信息那么该类就需要进行该接口 environmentAware 的实现
  • 实现 environmentAware 这个接口所提供的方法 setEnvironment()
  • 通过 environment 进行配置信息获取

2.8、BeanFoctoryAware(常用)

  • 负责生产和管理Bean的工厂
  • 简单来说就是可以获取到BeanFactory,然后可以针对BeanFactory工厂做出自己想要的,比如获取Bean,判断Bean是否在容器等等。

2.8.1、使用例子

2.9、BeanNameAware(常用)

  • 组件在IOC容器里面的名字
  • BeanNameAware接口的作用就是让实现这个接口的Bean知道自己在Spring IOC容器里的名字

使用场景,比如一个service的实现类中,有两个接口的实现类,但是A需要调用B,涉及到事务,可能就会失效,就可以采用自己类调方法,就可以用这个了。

2.9.1、使用例子

@Component
public class Tiger implements BeanNameAware {

@Override
public void setBeanName(String name) {
System.err.println("Bean的名字:" + name);
}

}

2.10、EmbeddedValueResolverAware(常用)

  • 可以获取Spring加载properties文件的属性值

2.10.1、使用例子

@Component
public class Tiger implements EmbeddedValueResolverAware {
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {

String val = resolver.resolveStringValue("当前操作系统为:${os.name},表达式(3*4)的结果:#{3*4}");
System.err.println("解析后的字符串=》" + val);
}

}

2.11、ResourceLoaderAware(常用)

  • 可获取Spring中配置的加载程序(ResourceLoader),用于对资源进行访问;可用于访问类,类路径或文件资源
  • Spring ResourceLoader为我们提供了一个统一的getResource()方法来通过资源路径检索外部资源。从而将资源或文件(例如文本文件、XML文件、属性文件或图像文件)加载到Spring应用程序上下文中的不同实现
  • 资源(Resource)接口
    • Resource是Spring中用于表示外部资源的通用接口。
    • Spring为Resource接口提供了以下6种实现。
      • UrlResourceClassPathResource
      • FileSystemResource
      • ServletContextResource
      • InputStreamResource
      • ByteArrayResource

【Spring【IOC】】——18、自定义组件中如何注入Spring底层的组件?_代码示例_03

  • ResourceLoader
    • getResource()方法将根据资源路径决定要实例化的Resource实现。 要获取ResourceLoader的引用,请实现ResourceLoaderAware接口。
Resource banner = resourceLoader.getResource("file:c:/temp/filesystemdata.txt");
  • ApplicationContext加载资源
    • 在Spring中,所有应用程序上下文都实现ResourceLoader接口。因此,所有应用程序上下文都可用于获取资源实例。
    • 要获取ApplicationContext的引用,请实现ApplicationContextAware接口。(请参考上面的ApplicationContextAware)
Resource banner = ctx.getResource("file:/user/local/filesystemdata.txt");

2.11.1、在springboot中使用示例

package com.zhz.aware;

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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* @author zhouhengzhe
* @date 2022/12/16
*/
@Component
public class CustomResourceLoaderAwareTest implements ResourceLoaderAware {

@Autowired
private ResourceLoader resourceLoader;

@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
try {
showResourceData();
} catch (IOException e) {
e.printStackTrace();
}
}

public void showResourceData() throws IOException
{
//This line will be changed for all versions of other examples
Resource banner = resourceLoader.getResource("classpath:spring-bean.xml");

InputStream in = banner.getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
reader.close();
}
}
3、Aware接口源码

具体核心方法:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
/**
* 主要是加载三大Aware:BeanNameAware->BeanClassLoaderAware->BeanFactoryAware
* 执行顺序:
* BeanNameAware
* BeanClassLoaderAware
* BeanFactoryAware
*/
invokeAwareMethods(beanName, bean);

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
/**
Bean的后置处理器前
* BeanPostProcessor处理器:
* ApplicationContextAwareProcessor
* BeanValidationPostProcessor
* InitDestroyAnnotationBeanPostProcessor
* AutowiredAnnotationBeanPostProcessor

* 处理对应的Aware接口:
* EnvironmentAware
* EmbeddedValueResolverAware
* ResourceLoaderAware
* ApplicationEventPublisherAware
* MessageSourceAware
* ApplicationStartupAware
* ApplicationContextAware
*/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
//初始化接口
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//Bean的后置处理器后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}
参考