详解-手写Spring框架(4)-Award回调

本文介绍了Spring框架的Aware回调功能,通过实现Aware接口使Bean能感知容器并与其交互。例如,BeanNameAware接口可用于获取Bean的名称。文章详细阐述了Aware回调的原理,包括实现接口、注册Bean、容器回调和回调测试,并展示了如何在实际开发中利用这一机制来满足复杂需求。
摘要由CSDN通过智能技术生成

摘要

本文将介绍Spring框架中的Aware回调功能,并通过模拟实现的方式来理解其原理和实现。我们将深入了解Aware接口的概念、使用方法以及在实际开发中的应用场景。

什么是Aware回调

  • Aware回调是Spring框架中的一种特性,它通过一组预定义的接口(Aware接口)使Bean能够意识到所处的环境或容器,并与之进行交互。这种回调机制使得Bean能够获取更多关于自身所在环境的信息或资源,从而灵活地进行操作。

  • Spring提供了多个Aware接口,如BeanFactoryAware、ApplicationContextAware等,每个接口都定义了一个回调方法,当Bean被初始化时,容器会自动调用该方法并传递相关上下文或资源对象给Bean。

为什么需要Aware回调

下面给一个例子来展示为什么spring需要Aware回调功能:

先给大家看一段bean对象userService的代码:

@Scope("prototype")//原型bean
@Component("userService")//用户定义的bean的名字,说明UserService是个bean
public class UserService {
    @Autowired//意思就是让spring自动为orderService注入值
    private OrderService orderService;

    @Autowired
    private String beanName;
    
    public void test(){
        System.out.println(orderService);//打印orderService属性
    }
}

其中我们新定义了一个beanName属性,并用@Autowired注解标记,我们的本意是想让spring容器自动给beanName属性赋值,值为自己的Bean的名字,即userService。

但是这种效果是无法达到的,因为@Autowired注解是根据beanName这个属性名去spring容器中找到bean对象,但是userService并不是bean的对象,只是bean的名字而已,所以在beanName上加@Autowired注解是无法实现该功能的,因此就需要Aware回调功能(BeanNameAware接口)来实现这样的效果。

本文文件目录

在这里插入图片描述

Aware回调的原理

Aware回调的原理可以简单概括为以下几个步骤:

步骤一:实现Aware接口

首先,我们需要在Bean类中实现对应的Aware接口,并重写回调方法。每个Aware接口都有其特定的作用和回调方法,可以根据需求选择实现相应的接口。

public interface BeanNameAware {
    void setBeanName(String beanName);
}

步骤二:注册Bean实例

然后,将实现了Aware接口的Bean实例(UserService)注册到Spring容器中。

以下是userService

@Scope("prototype")//原型bean
@Component("userService")//用户定义的bean的名字,说明UserService是个bean
public class UserService implements BeanNameAware {
    @Autowired//意思就是让spring自动为orderService注入值
    private OrderService orderService;

    private String beanName;
    @Override
    public void setBeanName(String name) {
        beanName=name;
    }

    public void test(){
        System.out.println(orderService);//打印orderService属性
        System.out.println(beanName);
    }
}

以下是Test类

public class Test {//测试书写的spring源码是否正确
    public static void main(String[] args) throws  InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        ApplicationContext applicationContext =new ApplicationContext(AppConfig.class);//传入配置文件
		//创建userService实例
        UserService userService=(UserService) applicationContext.getBean("userService");
        userService.test();//尝试测试依赖注入,打印的应该是null
    }
}

步骤三:容器回调

在Bean被初始化时,Spring容器会检测到Bean实现了Aware接口,并自动调用回调方法,将相关上下文或资源对象传递给Bean。

以下为ApplicationContext中的createBean方法

    public Object createBean(String beanName,BeanDefinition beanDefinition) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class clazz=beanDefinition.getClazz();
        //实例化得到对象
        Object instance=clazz.getDeclaredConstructor().newInstance();
		
		.......
		
        //判断当前实例对象是否实现了BeanNameAware接口
        if(instance instanceof BeanNameAware){
            //如果实现,就让spring调用setBeanName方法,将当前bean名传给该方法
            ((BeanNameAware)instance).setBeanName(beanName);
        }
        return instance;

    }

PS:注意此时在userService中的beanName属性不可以添加@Autowired注释,因为已经不是使用自动注入的方式,添加之后会出现空指针错误,自动注入无法找到bean的名字。

步骤四:回调测试

Main函数运行后结果:(可以看出已经打印出了userService的bean名)
在这里插入图片描述

总结

本文通过模拟实现Spring的Aware回调功能,介绍了Aware接口的概念、使用方法和实现步骤。Aware回调机制使得Bean能够意识到自身所处的环境或容器,并与之进行交互,获取所需的上下文或资源对象。在实际开发中,我们可以利用Aware回调来实现更灵活和可定制的功能,满足各种复杂的业务需求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值