方案本文是学习《Spring 手撸专栏》第 10 章笔记,主要记录我的一些debug调试过程,方便后期复习。具体学习,大家可以去看一下这个专栏,强烈推荐。
其实在有了AOP的核心功能实现后,把这部分功能服务融入到 Spring 其实也不难,只不过要解决几个问题,包括:怎么借着 BeanPostProcessor 把动态代理融入到 Bean 的生命周期中,以及如何组装各项切点、拦截、前置的功能和适配对应的代理器。整体设计结构如下图:
为了可以让对象创建过程中,能把xml中配置的代理对象也就是切面的一些类对象实例化,就需要用到 BeanPostProcessor 提供的方法,因为这个类的中的方法可以分别作用与 Bean 对象执行初始化前后修改 Bean 的对象的扩展信息。但这里需要集合于 BeanPostProcessor 实现新的接口和实现类,这样才能定向获取对应的类信息。但因为创建的是代理对象不是之前流程里的普通对象,所以我们需要前置于其他对象的创建,所以在实际开发的过程中,需要在 AbstractAutowireCapableBeanFactory#createBean 优先完成 Bean 对象的判断,是否需要代理,有则直接返回代理对象。在Spring的源码中会有 createBean 和 doCreateBean 的方法拆分这里还包括要解决方法拦截器的具体功能,提供一些 BeforeAdvice、AfterAdvice 的实现,让用户可以更简化的使用切面功能。除此之外还包括需要包装切面表达式以及拦截方法的整合,以及提供不同类型的代理方式的代理工厂,来包装我们的切面服务。 debug调试
因为创建的是代理对象不是之前流程里的普通对象,所以我们需要前置于其他对象的创建,所以在实际开发的过程中,需要在 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 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; }