在原生Spring框架中,其实框架给了很多在创建Bean之前的一些自定义的回调方法
可以让你自由度更高的自定义创建出来的Bean,比如各种Aware接口以及初始出Bean方法
那咱们也模仿Spring也做同样的事情
第一步:定义Aware或者初始化bean的接口
public interface BeanNameAware {
public void setBeanName();
}
public interface InitializingBean {
void afterPropertiesSet();
}
第二步:让自己写的bean实现Aware接口
实现接口,就必然要重写接口方法,比如我们将beanName设置成yu
@Component("yuWenWenService")
public class YuWenWenService implements BeanNameAware {
@Autowired
private MiaoWenWenService miaoWenWenService;
public String beanName;
@Override
public void setBeanName() {
beanName="yu";
}
public void test() {
System.out.println(miaoWenWenService);
System.out.println(beanName);
}
}
第三步:在ApplicationContext回调接口方法
在上一篇文章编写代码时,我们已经实装了,根据反射创建对象,以及进行属性的依赖注入
private Object createBean(BeanDefinition beanDefinition)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 第一步:创建对象
Object o = beanDefinition.getClazz().getDeclaredConstructor().newInstance();
// 第二部:依赖注入
// 先通过反射拿到这个对象的私有属性
Field[] declaredFields = o.getClass().getDeclaredFields();
// 遍历私有属性
for (Field field : declaredFields) {
// 判断私有属性的是否持有@Autowired
if (field.isAnnotationPresent(Autowired.class)) {
// 如果持有@Autowired 就从单例池里拿这个bean并赋值
Object bean = getBean(field.getName());
// 默认是不允许设置私有属性的值的 此处必须得改成true
field.setAccessible(true);
// 实现依赖注入
field.set(o, bean);
}
}
// 第三步:Aware回调以及初始化方法
。。。。。。。。。。
return o;
}
这次依赖注入完成之后,我们就要进行aware回调和初始化bean
// 第三步:Aware回调以及初始化方法
if (o instanceof BeanNameAware){
((BeanNameAware) o).setBeanName();
}
if (o instanceof InitializingBean){
((InitializingBean) o).afterPropertiesSet();
}
如此一来,一个bean的生命周期已经进行了 创建对象->属性依赖注入->Aware回调->初始化回调
我们来测试一下是否成功回调
public class ApplicationTest {
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
YuWenWenApplicationContext yuWenWenApplicationContext = new YuWenWenApplicationContext(AppConfig.class);
YuWenWenService yuWenWenService = (YuWenWenService) yuWenWenApplicationContext.getBean("yuWenWenService");
yuWenWenService.test();
}
}
测试成功,已经成功把beanName赋值给yu了
com.sbi.service.MiaoWenWenService@7aec35a
yu
第五步:在原生的Spring框架中,除了Aware,和初始化回调方法
还有一个叫后置处理器(BeanPostProcessor)可以自定义Bean
定义一个BeanPostProcessor的接口(这个接口有两个方法,一个是初始化前,一个是初始化后)
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean) {
return bean;
}
default Object postProcessAfterInitialization(Object bean) {
return bean;
}
}
定义自己的BeanPostProcessor去实现这两个方法
@Component("yuWenWenBeanPostProcessor")
public class YuWenWenBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean) {
System.out.println("后置处理器,初始化前");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean) {
System.out.println("后置处理器,初始化后");
return bean;
}
}
继续编写ApplicationContext的逻辑,在之前的scan方法中加入这段逻辑
//判断是否持有Component注解。。。。。。。
//扫描@Comptent注解发现有实现BeanPostProcessor的类
if (BeanPostProcessor.class.isAssignableFrom(aClass)){
// 就将此类通过反射创建出来
BeanPostProcessor beanPostProcessor = (BeanPostProcessor)aClass.getDeclaredConstructor().newInstance();
// 将这个后置处理器加到list里
beanPostProcessorList.add(beanPostProcessor);
}
这样一来就在创建Bean的时候逻辑就变成以下这个样子
// 第三步:Aware回调以及初始化方法
if (o instanceof BeanNameAware) {
((BeanNameAware) o).setBeanName();
}
// 第四步:BeanPostProcessor的前置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessBeforeInitialization(o);
}
// 第五步:初始化方法
if (o instanceof InitializingBean) {
((InitializingBean) o).afterPropertiesSet();
}
// 第六步:BeanPostProcessor的后置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessAfterInitialization(o);
}
测试一下:成功
后置处理器,初始化前 后置处理器,初始化后
Aware和初始化回调还是和 BeanPostProcessor的用法上还是有区别
Aware和初始化回调:是指当前类实现接口,对当前Bean进行自定义设置
后置处理器(BeanPostProcessor):是可以对所有的Bean进行改造,当然也可以对某一个进行自定义设置
YuWenWenApplicationContext源码奉上
package com.sbi.config;
import com.sbi.annotation.Autowired;
import com.sbi.annotation.Component;
import com.sbi.annotation.ComponentScan;
import com.sbi.annotation.Scope;
import com.sbi.service.BeanPostProcessor;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class YuWenWenApplicationContext {
private Class config;
// 单例池(key:beanName,value:bean)
private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
// BeanDefinitionMap(key:beanName,value:类描述)
private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
// BeanPostProcessorList
private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();
public YuWenWenApplicationContext(Class config)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
this.config = config;
// 扫描bean,并且得到所有beanDefinition放在beanDefinitionMap里
scan(config);
// 循环beanDefinitionMap全部
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
if (entry.getValue().getScope().equals("singleton")) {
// 创建bean
Object bean = createBean(entry.getValue());
// 将创建好的bean放到单例池等待getBean调用
singletonObjects.put(entry.getKey(), bean);
}
}
}
private Object createBean(BeanDefinition beanDefinition)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 第一步:创建对象
Object o = beanDefinition.getClazz().getDeclaredConstructor().newInstance();
// 第二部:依赖注入
// 先通过反射拿到这个对象的私有属性
Field[] declaredFields = o.getClass().getDeclaredFields();
// 遍历私有属性
for (Field field : declaredFields) {
// 判断私有属性的是否持有@Autowired
if (field.isAnnotationPresent(Autowired.class)) {
// 如果持有@Autowired 就从单例池里拿这个bean并赋值
Object bean = getBean(field.getName());
// 默认是不允许设置私有属性的值的 此处必须得改成true
field.setAccessible(true);
// 实现依赖注入
field.set(o, bean);
}
}
// 第三步:Aware回调以及初始化方法
if (o instanceof BeanNameAware) {
((BeanNameAware) o).setBeanName();
}
// 第四步:BeanPostProcessor的前置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessBeforeInitialization(o);
}
// 第五步:初始化方法
if (o instanceof InitializingBean) {
((InitializingBean) o).afterPropertiesSet();
}
// 第六步:BeanPostProcessor的后置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessAfterInitialization(o);
}
return o;
}
private void scan(Class config)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 此处得到@ComponentScan的扫描路径
ComponentScan path = (ComponentScan) config.getDeclaredAnnotation(ComponentScan.class);
// 得到一个类加载器 classpath下面用AppClassLoader
ClassLoader classLoader = YuWenWenApplicationContext.class.getClassLoader();
// 得到类的包路径(此处为com.sbi.service格式需要改成com/sbi/service)
URL resource = classLoader.getResource(path.value().replace(".", "/"));
// 得到包下的文件
File file = new File(resource.getFile());
if (file.isDirectory()) {
// 得到包下所有的文件信息
File[] files = file.listFiles();
for (File f : files) {
String absolutePath = f.getAbsolutePath();
String pathReplaceBefore = absolutePath
.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
String pathreplaceAfter = pathReplaceBefore.replace("\\", ".");
// 此处最终需要com.sbi.service.YuWenWenService格式
Class<?> aClass = classLoader.loadClass(pathreplaceAfter);
// 如果这个类拥有@Component注解,那么我们就要反射
if (aClass.isAnnotationPresent(Component.class)) {
//扫描@Comptent注解发现有实现BeanPostProcessor的类
if (BeanPostProcessor.class.isAssignableFrom(aClass)) {
// 就将此类通过反射创建出来
BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.getDeclaredConstructor()
.newInstance();
// 将这个后置处理器加到list里
beanPostProcessorList.add(beanPostProcessor);
}
Component declaredAnnotation = aClass.getDeclaredAnnotation(Component.class);
// 拿到@Component的value值也就是bean的名字
String springbeanName = declaredAnnotation.value();
// 描述类创建
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(aClass);
// 判断这个类是否还持有@Scope的其他作用域(spring 一共有四种作用域,默认不指定的情况下就是单例)
if (aClass.isAnnotationPresent(Scope.class)) {
Scope declaredAnnotation1 = aClass.getDeclaredAnnotation(Scope.class);
beanDefinition.setScope(declaredAnnotation1.value());
} else {
// spring默认不指定的情况下就是单例作用域
beanDefinition.setScope("singleton");
}
// 将类信息放到beanDefinitionMap里
beanDefinitionMap.put(springbeanName, beanDefinition);
}
}
}
}
public Object getBean(String beanName)
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
//去beanDefinitionMap寻找是否有自己的类描述
if (beanDefinitionMap.containsKey(beanName)) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
//如果是单例bean,直接从单例池拿
if (beanDefinition.getScope().equals("singleton")) {
Object bean = singletonObjects.get(beanName);
return bean;
//如果是原型bean就给创建一个新的bean
} else {
Object bean = createBean(beanDefinition);
return bean;
}
//没招到的情况下就说明此类并没有加@Competent
} else {
throw new NullPointerException("此类不存在");
}
}
}