手写模拟Spring
0、上集回顾
手写模拟一个简单的Spring(上)
手写模拟一个简单的Spring(中)
4、手写中阶功能-- 依赖注入
简单的bean创建已经写好了,但是我们实际使用的Spring可不是单个bean独立使用的。接下来我们就来实现一个 @Autowired 功能
4.1、定义注解
这里我们仿造Spring,定义一个@Autowired注解。我们去掉里面的方法,就使用空注解就行,当成一个标记来使用。这个注解是在属性上使用的。
4.2、实现依赖注入
接下来开始实现依赖注入功能。
依赖注入失败!! 哈哈,我们还得处理对应的逻辑才行
依赖注入的时机是发生在bean创建的时候,所以我们这里得改造doCreateBean方法了。
改造前:
开始改造,我们首先得拿到要注入的属性才行,然后获得bean,使用反射进行属性注入填充。
效果查看,可以看到我们已经拿到对应的bean了。
5、手写高阶功能-- AOP
这里我们来挑战下,自己写个AOP的实现。在Spring中AOP是通过BeanPostProcessor来实现的,我们也仿造着来做
5.1、定义接口 BeanPostProcessor,编写方法
实现接口,AOP的功能是在bean初始化后执行的,所以这里重写了postProcessAfterInitialization方法
@Component
public class YearAopProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 因为每个bean的生命周期都会经过这个方法,所以这里如果想对单个bean进行处理得做判断
if (beanName.equals("orderService")) {
// 如果是orderService,我们进行动态代理操作
// 这里我们选择使用JDK的动态代理,得基于接口来实现
Object proxyInstance = Proxy.newProxyInstance(YearAopProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 执行代理逻辑
System.out.println("我执行了代理逻辑");
// 然后再执行被代理目标类的方法
return method.invoke(bean, args);
}
});
return proxyInstance;
}
// 没有做任何处理
return bean;
}
}
5.2、调用方法
现在运行肯定是没有任何效果的,毕竟我们的方法都没有地方被调用。那么怎么样才能让方法被调用呢?或者说我们怎么样才能拿到我们自己写的BeanPostProcessor的实现类?
这里得在扫描的逻辑里面进行处理,把扫描到的后置处理器先缓存起来。
直接在创建bean的过程中完成调用。
效果演示。这里可以看到缓存进单例池的对象是代理对象,调用对应方法也进入了代理逻辑。
6、完结撒花🌹
简单的功能模拟就写的这儿了,我会把源码地址附上
源码传送门