https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop

根据 Spring 源码,再 Spring 完成 bean 的生命周期回调之后,开始进行 AOP 代理,所调用的就是 BeanPostProcessor 的 postProcessAfterInitialization 方法

  1. @Override
  2. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  3. throws BeansException {
  4. Object result = existingBean;
  5. // 执行直接实现了 BeanPostProcessor 的类的 postProcessAfterInitialization 方法
  6. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  7. Object current = processor.postProcessAfterInitialization(result, beanName);
  8. if (current == null) {
  9. return result;
  10. }
  11. result = current;
  12. }
  13. return result;
  14. }

既然知道了原理,我么也可以实现了一个 AOP,我们使用 @Import 注解导入的方式(方便扩展)

  1. @Service
  2. public class UserService {
  3. public void testAop() {
  4. System.out.println("UserService test aop");
  5. }
  6. }
  7. public class CustomAopBeanPostProcessor implements BeanPostProcessor {
  8. @Override
  9. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  10. if (bean instanceof UserService) {
  11. bean = CglibUtils.getProxy(bean.getClass(), new MethodInterceptor() {
  12. @Override
  13. public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  14. System.out.println("aop ----------");
  15. Object result = methodProxy.invokeSuper(o, args);
  16. return result;
  17. }
  18. });
  19. }
  20. return bean;
  21. }
  22. }
  23. @Configuration
  24. @ComponentScan("org.wesoft.spring.aop")
  25. @EnableAspectJAutoProxy
  26. @Import(CustomAopBeanPostProcessor.class)
  27. public class AppConfig {
  28. }
  29. public class App {
  30. public static void main(String[] args) {
  31. AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
  32. ac.register(AppConfig.class);
  33. ac.refresh();
  34. ac.getBean(UserService.class).testAop();
  35. }
  36. }
  37. // 运行结果
  38. aop ----------
  39. UserService test aop

什么是 AOP

与 OOP 对比,面向切面,传统的 OOP 开发中的代码逻辑是自上而下的,而这些过程会产生一些横切性问题,这些横切性问题和我们的业务关系不大,这些横切问题不会影响到主逻辑的实现,但是会散落到代码的各个部分,难以维护,AOP 是处理一些横切性的问题,AOP 的编程思想就是把这些问题和主业务逻辑分开,达到与主业务逻辑解耦的目的。使代码的重用性和开发效率更高

应用场景

  • 日志记录
  • 权限验证
  • 效率检查
  • 事务管理
  • 异常处理

相关概念

  • Aspect: 切面,一个综合体.
  • Join point: 连接点,如方法的执行和异常的处理,在 Spring AOP 中,指的是方法的执行.
  • Advice: 通知,包括“around”, “before” and “after” 通知
  • Pointcut: 匹配连接点,是一段表达式,一个集合.
  • Introduction: 代表类型声明其他方法或字段
  • Target object: 目标对象.
  • AOP proxy: 代理对象
  • Weaving: 将通知应用到切点的过程

通知类型

  • Before advice: Advice that runs before a join point but that does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).
  • After returning advice: Advice to be run after a join point completes normally (for example, if a method returns without throwing an exception).
  • After throwing advice: Advice to be executed if a method exits by throwing an exception.
  • After (finally) advice: Advice to be executed regardless of the means by which a join point exits (normal or exceptional return).
  • Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.

execution

  1. execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
  2. throws-pattern?)

Spring 第一次调用后置处理器

在 createBean 中,第一次调用后置处理器时,完成了,是否要代理 Bean 的逻辑

  1. try {
  2. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  3. // 给 BeanPostProcessors 来返回代理对象 代替 目标对象
  4. // ★★★ 第一次调用后置处理器---在 bean 被实例化之前调用
  5. // 此处调用的目的是,判断当前的 bean 将来是否能够被代理,
  6. // 实例化之前解析 bean,来判断这个 bean 是不是需要代理
  7. // 这里会将可能会被代理的类,放入 advisedBeans(Map)中,其中 key 为 bean 的名字,value 为 是否需要被代理
  8. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  9. if (bean != null) {
  10. return bean;
  11. }
  12. }
  13. @Nullable
  14. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  15. Object bean = null;
  16. // 判断 实例化处理器是否已经开始工作
  17. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  18. // Make sure bean class is actually resolved at this point.
  19. // 是否不是一个合成类
  20. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  21. Class<?> targetType = determineTargetType(beanName, mbd);
  22. if (targetType != null) {
  23. // 判断是否需要被代理
  24. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  25. if (bean != null) {
  26. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  27. }
  28. }
  29. }
  30. mbd.beforeInstantiationResolved = (bean != null);
  31. }
  32. return bean;
  33. }
  34. @Nullable
  35. protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  36. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  37. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  38. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  39. // 调用后置处理器,如果开启了 @EnableAspectJAutoProxy
  40. // 就会调用 AnnotationAwareAspectJAutoProxyCreator 的 postProcessBeforeInstantiation
  41. Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
  42. if (result != null) {
  43. return result;
  44. }
  45. }
  46. }
  47. return null;
  48. }

这里调用了 AbstractAutoProxyCreator 的 postProcessBeforeInstantiation 方法,其中 this.advisedBeans 中存放了是否需要代理的 bean,其中 key = beanName,value = boolean,表示是否需要被代理

  1. @Override
  2. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
  3. // 获取 bean 的名字,如果是 FactoryBean 的话,给他的前面加一个 & 符号
  4. Object cacheKey = getCacheKey(beanClass, beanName);
  5. if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
  6. // 判断 advisedBeans 是否是包含不需要被代理的类
  7. // advisedBeans 存放着两种 bean
  8. // 1、不能被代理,比如 切面(Aspect),配置类(AppConfig),后置处理器(BeanPostProcessor),这些都是不能被代理的类
  9. // 2、已经被代理的被,因为不需要继续被代理
  10. if (this.advisedBeans.containsKey(cacheKey)) {
  11. return null;
  12. }
  13. // 判断是不是不需要被代理的类,如果是,则放到 advisedBeans 中
  14. // 先判断是不是基础 Bean 或者 prototype 类型的 bean
  15. if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
  16. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  17. return null;
  18. }
  19. }
  20. // Create proxy here if we have a custom TargetSource.
  21. // Suppresses unnecessary default instantiation of the target bean:
  22. // The TargetSource will handle target instances in a custom fashion.
  23. TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
  24. if (targetSource != null) {
  25. if (StringUtils.hasLength(beanName)) {
  26. this.targetSourcedBeans.add(beanName);
  27. }
  28. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  29. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
  30. this.proxyTypes.put(cacheKey, proxy.getClass());
  31. return proxy;
  32. }
  33. return null;
  34. }

Spring 开始创建 AOP 代理对象

  1. if (mbd == null || !mbd.isSynthetic()) {
  2. // ★★★ 开始执行对象的代理(AOP)
  3. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  4. }
  5. @Override
  6. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  7. throws BeansException {
  8. Object result = existingBean;
  9. // 执行直接实现了 BeanPostProcessor 的类的 postProcessAfterInitialization 方法
  10. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  11. Object current = processor.postProcessAfterInitialization(result, beanName);
  12. if (current == null) {
  13. return result;
  14. }
  15. result = current;
  16. }
  17. return result;
  18. }
  19. @Override
  20. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  21. if (bean != null) {
  22. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  23. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  24. // ★★★ 关键代码:开始执行代理
  25. return wrapIfNecessary(bean, beanName, cacheKey);
  26. }
  27. }
  28. return bean;
  29. }

Spring 会先判断这个 bean 是否在 advisedBeans 中,在判断 bean 的类型,是否时不需要被代理的类型,然后找出我们提供的切面,在检查我们提供 bean 是否符合这个切面

  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  2. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  3. return bean;
  4. }
  5. // 判断 在不在 advisedBeans 里
  6. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  7. return bean;
  8. }
  9. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  10. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  11. return bean;
  12. }
  13. // Create proxy if we have advice.
  14. // ★ 判断这个 bean 是否符合我们提供的切面规则
  15. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  16. if (specificInterceptors != DO_NOT_PROXY) {
  17. // 需要被代理的类
  18. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  19. // ★★★ 关键代码:开始创建代理
  20. Object proxy = createProxy(
  21. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  22. this.proxyTypes.put(cacheKey, proxy.getClass());
  23. return proxy;
  24. }
  25. // 代理完成,将这个对象放入 advisedBeans,并标记为 不需要被代理
  26. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  27. return bean;
  28. }

Spring 开始创建代理对象

  1. if (mbd == null || !mbd.isSynthetic()) {
  2. // ★★★ 开始执行对象的代理(AOP)
  3. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  4. }
  5. @Override
  6. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  7. throws BeansException {
  8. Object result = existingBean;
  9. // 执行直接实现了 BeanPostProcessor 的类的 postProcessAfterInitialization 方法
  10. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  11. Object current = processor.postProcessAfterInitialization(result, beanName);
  12. if (current == null) {
  13. return result;
  14. }
  15. result = current;
  16. }
  17. return result;
  18. }
  19. @Override
  20. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  21. if (bean != null) {
  22. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  23. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  24. // ★★★ 关键代码:开始执行代理
  25. return wrapIfNecessary(bean, beanName, cacheKey);
  26. }
  27. }
  28. return bean;
  29. }
  30. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  31. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  32. return bean;
  33. }
  34. // 判断 在不在 advisedBeans 里
  35. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  36. return bean;
  37. }
  38. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  39. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  40. return bean;
  41. }
  42. // Create proxy if we have advice.
  43. // ★ 判断这个 bean 是否符合我们提供的切面规则
  44. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  45. if (specificInterceptors != DO_NOT_PROXY) {
  46. // 需要被代理的类
  47. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  48. // ★★★ 关键代码:开始创建代理
  49. Object proxy = createProxy(
  50. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  51. this.proxyTypes.put(cacheKey, proxy.getClass());
  52. return proxy;
  53. }
  54. // 代理完成,将这个对象放入 advisedBeans,并标记为 不需要被代理
  55. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  56. return bean;
  57. }