【Spring注解驱动开发】自定义组件如何注入Spring底层的组件?看了这篇我才真正理解了原理!

接下来,我们就挑选几个常用的XxxAware接口来进行简单的说明。

ApplicationContextAware接口使用的比较多,我们先来说说这个接口,通过ApplicationContextAware接口我们可以获取到IOC容器。

首先,我们创建一个Blue类,并实现ApplicationContextAware接口,在实现的setApplicationContext()中将ApplicationContext输出,如下所示。

package io.mykit.spring.plugins.register.bean;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**

  • @author binghe
  • @version 1.0.0
  • @description 测试ApplicationContextAware接口
    */
    public class Blue implements ApplicationContextAware {
    private ApplicationContext applicationContext
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println(“传入的ioc:” + applicationContext);
    this.applicationContext = applicationContext;
    }
    }

我们也可以为Blue类同时实现几个XxxAware接口,例如,使Blue类再实现一个BeanNameAware接口,我们可以通过BeanNameAware接口获取到当前bean在Spring容器中的名称,如下所示。

package io.mykit.spring.plugins.register.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**

  • @author binghe
  • @version 1.0.0
  • @description 测试ApplicationContextAware接口
    */
    public class Blue implements ApplicationContextAware, BeanNameAware {
    private ApplicationContext applicationContext
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println(“传入的ioc:” + applicationContext);
    this.applicationContext = applicationContext;
    }

@Override
public void setBeanName(String name) {
System.out.println(“当前bean的名字”);
}
}

接下来,我们再实现一个EmbeddedValueResolverAware接口,我们通过EmbeddedValueResolverAware接口能够获取到StringValue解析器。如下所示。

package io.mykit.spring.plugins.register.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.util.StringValueResolver;
/**

  • @author binghe
  • @version 1.0.0
  • @description 测试ApplicationContextAware接口
    */
    public class Blue implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println(“传入的ioc:” + applicationContext);
    this.applicationContext = applicationContext;
    }

@Override
public void setBeanName(String name) {
System.out.println(“当前bean的名字”);
}

@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
String resolveStringValue = resolver.resolveStringValue(“你好${os.name} 年龄:#{20*18}”);
System.out.println(“解析后的字符串为:” + resolveStringValue);
}
}

接下来,我们需要在Blue类上标注@Component注解将Blue类添加到IOC容器中,如下所示。

@Component
public class Blue implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

运行AutowiredTest类的testAutowired02()方法,输出的结果信息如下所示。

postProcessBeforeInitialization…autowiredConfig=>io.mykit.spring.plugins.register.config.AutowiredConfig E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIBd3c83622@1c93084c
postProcessAfterInitialization…autowiredConfig=>io.mykit.spring.plugins.register.config.AutowiredConfig E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIBd3c83622@1c93084c
postProcessBeforeInitialization…personDao=>PersonDao{remark=‘1’}
postProcessAfterInitialization…personDao=>PersonDao{remark=‘1’}
postProcessBeforeInitialization…personDao2=>PersonDao{remark=‘2’}
postProcessAfterInitialization…personDao2=>PersonDao{remark=‘2’}
postProcessBeforeInitialization…personService=>PersonService{personDao=PersonDao{remark=‘2’}}
postProcessAfterInitialization…personService=>PersonService{personDao=PersonDao{remark=‘2’}}
postProcessBeforeInitialization…personController=>io.mykit.spring.plugins.register.controller.PersonController@48ae9b55
postProcessAfterInitialization…personController=>io.mykit.spring.plugins.register.controller.PersonController@48ae9b55
执行了Animal类的无参数构造方法
postProcessBeforeInitialization…animal=>io.mykit.spring.plugins.register.bean.Animal@c267ef4
执行了Animal类的初始化方法。。。。。
postProcessAfterInitialization…animal=>io.mykit.spring.plugins.register.bean.Animal@c267ef4
当前bean的名字:blue
解析后的字符串为:你好Windows 10 年龄:360
传入的ioc:org.springframework.context.annotation.AnnotationConfigApplicationContext@5ecddf8f, started on Wed Aug 19 00:10:13 CST 2020
postProcessBeforeInitialization…blue=>io.mykit.spring.plugins.register.bean.Blue@55182842
postProcessAfterInitialization…blue=>io.mykit.spring.plugins.register.bean.Blue@55182842
Cat类的构造方法…
postProcessBeforeInitialization…cat=>io.mykit.spring.plugins.register.bean.Cat@76505305
Cat的postConstruct()方法…
postProcessAfterInitialization…cat=>io.mykit.spring.plugins.register.bean.Cat@76505305
调用了Dog的有参构造方法
postProcessBeforeInitialization…dog=>Dog{cat=io.mykit.spring.plugins.register.bean.Cat@76505305}
postProcessAfterInitialization…dog=>Dog{cat=io.mykit.spring.plugins.register.bean.Cat@76505305}
postProcessBeforeInitialization…employee=>io.mykit.spring.plugins.register.bean.Employee@74235045
postProcessAfterInitialization…employee=>io.mykit.spring.plugins.register.bean.Employee@74235045
postProcessBeforeInitialization…fish=>Fish{cat=io.mykit.spring.plugins.register.bean.Cat@76505305}
postProcessAfterInitialization…fish=>Fish{cat=io.mykit.spring.plugins.register.bean.Cat@76505305}
Fish{cat=io.mykit.spring.plugins.register.bean.Cat@76505305}
Cat的preDestroy()方法…
执行了Animal类的销毁方法。。。。。

输出结果中有如下信息。

当前bean的名字:blue
解析后的字符串为:你好Windows 10 年龄:360
传入的ioc:org.springframework.context.annotation.AnnotationConfigApplicationContext@5ecddf8f, started on Wed Aug 19 00:10:13 CST 2020

说明正确的输出了结果信息。

XxxAware原理

XxxAware的底层原理是由XxxAwareProcessor类实现的, 例如,我们这里以ApplicationContextAware接口为例,ApplicationContextAware接口的底层原理就是由ApplicationContextAwareProcessor类实现的。从ApplicationContextAwareProcessor类的源码可以看出,其实现了BeanPostProcessor接口,本质上都是后置处理器。

class ApplicationContextAwareProcessor implements BeanPostProcessor

接下来,我们就以分析ApplicationContextAware接口的原理为例,看看Spring是怎么将ApplicationContext对象注入到Blue类中的。

我们在Blue类的setApplicationContext()方法上打一个断点,如下所示。

接下来,我们以debug的方式来运行AutowiredTest类的testAutowired02()方法,

这里,我们可以看到,实际上ApplicationContext对象已经注入到Blue类中的setApplicationContext()方法中了。我们在IDEA的方法调用栈中选择postProcessBeforeInitialization()方法,如下所示。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Java高频面试专题合集解析:

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

更多Java架构进阶资料展示

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
3)]

[外链图片转存中…(img-OvQxR2HL-1713407686563)]

[外链图片转存中…(img-l0a0ibPH-1713407686563)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值