引言
我们上一篇文章中,已经完成了一个复杂的依赖注入功能。这篇文章我们实习Spring中回调的功能,也就是一系列的Aware接口。
我们开始吧😁!
本文所有的代码都在这个项目工程里,大家需要的时候可以随时取用。传送门
我们先回顾下Aware类接口的使用,就拿最简单的一个接口BeanNameAware来说,我们自已定的类比如说上文的UserService类实现它,Spring的上下文会将beanName注入到它的属性中去,这样我们就可以拿到了这个UserService在Spring容器中的名称。
ok,具体要怎么实现呢?
首先,我们需要创建一个BeanNameAware接口,具体代码如下:
package com.zhu.spring;
public interface BeanNameAware {
void setBeanName(String beanName);
}
然后在实现它,业务代码如下:
package com.zhu.service;
import com.zhu.spring.Autowired;
import com.zhu.spring.BeanNameAware;
import com.zhu.spring.Component;
import com.zhu.spring.Scope;
@Component
@Scope("singleton")
public class UserService implements BeanNameAware {
@Autowired
private OrderService orderService;
private String beanName;
public void test(){
System.out.println(orderService+"|"+beanName);
}
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
}
现在的问题就是如何将值赋予给实现这个接口的累了,这一点很简单。
我们只需要在创建bean的代码中做一点点🤏小的修改,即可实现,代码如下:
Object instance = clazz.getConstructor().newInstance();
// simple dependency injection
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
//change true ,can assign private
field.setAccessible(true);
String fieldName = field.getName();
Object bean = getBean(fieldName);
field.set(instance, bean);
}
}
//check bean name aware
//判断这个对象有没有实现BeanNameAware接口
if (instance instanceof BeanNameAware) {
//实现了,就强制转换成这个接口,然后调用它的setBeanName方法
//force cast to BeanNameAare and call its method
((BeanNameAware)instance).setBeanName(beanName);
}
完成之后,执行我们的测试代码,发现已经成功注入。在Spring中还有很多这样的Aware接口其实都是以类似这样的方式实现的,咋一看十分神奇,其实实现的原理很简单。