实现Spring底层机制-03
7.阶段5-后置处理器的实现
7.1分析
阶段5目标:bean后置处理器的实现
7.2代码实现
新增:
1.创建 InitializingBean 接口,实现该接口的 Bean 需要实现 Bean 的初始化方法
bean后置处理器的两个方法,调用时机分别在 Bean 初始化方法的前后。因此要实现bean后置处理器,首先要实现 Bean 的初始化方法。
可以参考原生 Spring 规范来定义这个接口
package com.li.spring.processor;
/**
* @author 李
* @version 1.0
* 说明:
* 1.根据 spring 原生机制定义了一个接口
* 2.该接口有一个方法 afterPropertiesSet(),
* 3.afterPropertiesSet() 在 bean的 setter方法后执行,相当于原生的spring的 bean初始化方法
* 4.当一个Bean实现了这个接口后,就要实现afterPropertiesSet(),即 bean的初始化方法
*/
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
2.为了测试,在MonsterService中实现该接口,并实现该方法,作为MonsterService的初始化方法
注:其他注解及自动装配的实现详见上一篇
package com.li.spring.component;
import com.li.spring.annotation.AutoWired;
import com.li.spring.annotation.Component;
import com.li.spring.annotation.Scope;
import com.li.spring.processor.InitializingBean;
/**
* @author 李
* @version 1.0
* MonsterService 是一个 Service
* 1.如果指定了value,那么在注入spring容器时,以你指定的为准
* 2.如果没有指定value,则使用类名(首字母小写)作为默认名
*/
@Component//(value = "monsterService") //将 MonsterService注入到自己的spring容器中
@Scope(value = "prototype")
public class MonsterService implements InitializingBean {
//使用自定义注解修饰属性,表示该属性通过容器完成依赖注入
// (说明:按照名字进行组装)
@AutoWired(required = true)
private MonsterDao monsterDao;
public void m1() {
monsterDao.hi();
}
/**
* 1.afterPropertiesSet()就是在bean的setter方法执行完毕之后,被spring容器调用
* 2.即 bean的初始化方法
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("MonsterService 初始化方法被调用");
}
}
3.修改MySpringApplicationContext.java,添加逻辑:在创建后bean实例后,判断是否需要进行初始化。
容器中常用的一个方法是,根据该类是否实现了某个接口,来判断该类是否要执行某个业务逻辑。这个接口被称为标记接口。
部分代码:
//完成createBean(BeanDefinition)方法
public Object createBean(BeanDefinition beanDefinition) {
//得到Bean的class对象
Class clazz = beanDefinition.getClazz();
try {
//反射创建bean实例
Object instance = clazz.getDeclaredConstructor().newInstance();
//todo 这里要加入依赖注入的业务逻辑
//1.遍历当前要创建对象的所有属性字段
for (Field declaredField : clazz.getDeclaredFields()) {
//2.判断字段是否有AutoWired注解
if (declaredField.isAnnotationPresent(AutoWired.class)) {
//判断是否需要自动装配
AutoWired autoWiredAnnotation =
declaredField.getAnnotation(AutoWired.class);
if (autoWiredAnnotation.required()) {
//3.得到字段的名称
String name = declaredField.getName();
//4.通过getBean()方法获取要组装的对象
//如果name对应的对象时单例的,就到单例池去获取,如果是多例的,就反射创建并返回
Object bean = getBean(name);
//5.进行组装
//暴破
declaredField.setAccessible(true);
declaredField.set(instance, bean);
}
}
}
System.out.println("======已创建好实例=====" + instance);
//todo 判断是否要执行bean的初始化方法
// 1.判断当前创建的 bean对象是否实现了 InitializingBean
// 2.instanceof 表示判断对象的运行类型 是不是 某个类型或某个类型的子类型
if (instance instanceof InitializingBean) {
//3.将instance转成接口类型,调用初始化方法
try {
((InitializingBean) instance).afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
}
return instance;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
//如果反射对象失败
return null;
}
4.测试类
//...
public class AppMain {
public static void main(Stri