本文是学习《Spring 手撸专栏》第 10 章笔记,主要记录我的一些debug调试过程,方便后期复习。具体学习,大家可以去看一下这个专栏,强烈推荐。
其实在有了AOP的核心功能实现后,把这部分功能服务融入到 Spring 其实也不难,只不过要解决几个问题,包括:怎么借着 BeanPostProcessor 把动态代理融入到 Bean 的生命周期中,以及如何组装各项切点、拦截、前置的功能和适配对应的代理器。整体设计结构如下图:
因为创建的是代理对象不是之前流程里的普通对象,所以我们需要前置于其他对象的创建,所以在实际开发的过程中,需要在 AbstractAutowireCapableBeanFactory#createBean 优先完成 Bean 对象的判断,是否需要代理,有则直接返回代理对象。
AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean = null;
try {
// 判断是否返回代理 Bean 对象
bean = resolveBeforeInstantiation(beanName, beanDefinition);
if (null != bean) {
return bean;
}
// 实例化 Bean
bean = createBeanInstance(beanDefinition, beanName, args);
...
}
...
}
AbstractAutowireCapableBeanFactory.java
protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
if (null != bean) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
return bean;
}
AbstractAutowireCapableBeanFactory.java
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName);
if (null != result) return result;
}
}
return null;
}
DefaultAdvisorAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (isInfrastructureClass(beanClass)) return null;
Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
ClassFilter classFilter = advisor.getPointcut().getClassFilter();
if (!classFilter.matches(beanClass)) continue;
AdvisedSupport advisedSupport = new AdvisedSupport();
TargetSource targetSource = null;
try {
targetSource = new TargetSource(beanClass.getDeclaredConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
advisedSupport.setTargetSource(targetSource);
advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
advisedSupport.setProxyTargetClass(false);
//这里面会调用代理方法。
return new ProxyFactory(advisedSupport).getProxy();
}
return null;
}