摘要
本文将介绍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回调来实现更灵活和可定制的功能,满足各种复杂的业务需求。