环境搭建

pom文件

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-aspects</artifactId>
  4. <version>4.3.12.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework</groupId>
  8. <artifactId>spring-context</artifactId>
  9. <version>4.3.12.RELEASE</version>
  10. </dependency>

1.被代理对象

  1. public class MathCalculator {
  2. public int div(int i, int j) {
  3. System.out.println("MathCalculator...div...");
  4. return i / j;
  5. }
  6. }

2.切面类

  1. @Aspect
  2. public class LogAspects {
  3. @Pointcut("execution(public int org.aop.MathCalculator.*(..))")
  4. public void pointCut() {}
  5. // @Before:在目标方法(即div方法)运行之前切入,public int com.meimeixia.aop.MathCalculator.div(int, int)这一串就是切入点表达式,指定在哪个方法切入
  6. @Before("pointCut()")
  7. public void logStart(JoinPoint joinPoint) {
  8. Object[] args = joinPoint.getArgs(); // 拿到参数列表,即目标方法运行需要的参数列表
  9. System.out.println(joinPoint.getSignature().getName() + "运行......@Before,参数列表是:{" + Arrays.asList(args) + "}");
  10. }
  11. // 在目标方法(即div方法)结束时被调用
  12. @After("pointCut()")
  13. public void logEnd(JoinPoint joinPoint) {
  14. System.out.println(joinPoint.getSignature().getName() + "结束......@After");
  15. }
  16. // 在目标方法(即div方法)正常返回了,有返回值,被调用
  17. @AfterReturning(value="pointCut()", returning="result")
  18. public void logReturn(JoinPoint joinPoint, Object result) {
  19. System.out.println("除法正常返回......@AfterReturning,运行结果是:{}"+result);
  20. }
  21. // 在目标方法(即div方法)出现异常,被调用
  22. @AfterThrowing(value = "pointCut()",throwing = "ex")
  23. public void logException(Throwable ex) {
  24. System.out.println("除法出现异常......异常信息:{}"+ex.getMessage());
  25. }
  26. }

用到了注解
@Aspect
@Pointcut(“execution(public int org.aop.MathCalculator.*(..))”)
@Before等

3.配置类

  1. @EnableAspectJAutoProxy
  2. @Configuration
  3. public class MainConfigOfAOP {
  4. // 将业务逻辑类(目标方法所在类)加入到容器中
  5. @Bean
  6. public MathCalculator calculator() {
  7. return new MathCalculator();
  8. }
  9. // 将切面类加入到容器中
  10. @Bean
  11. public LogAspects logAspects() {
  12. return new LogAspects();
  13. }
  14. }

用到了注解@EnableAspectJAutoProxy

4.测试方法

  1. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
  2. // 我们要使用Spring容器中的组件
  3. MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
  4. mathCalculator.div(1, 0);

入口分析@EnableAspectJAutoProxy

作用就是:@Import(AspectJAutoProxyRegistrar.class)
向容器注册bean

@EnableAspectJAutoProxy源码

  1. class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
  2. /**
  3. * Register, escalate, and configure the AspectJ auto proxy creator based on the value
  4. * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
  5. * {@code @Configuration} class.
  6. 核心:注册AnnotationAwareAspectJAutoProxyCreator
  7. */
  8. @Override
  9. public void registerBeanDefinitions(
  10. AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  11. //方法1:注册名为internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator类
  12. AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  13. //方法2:提取注解的属性,正常都是空,如果有属性,则调用下面AopConfigUtils的方法,对aop处理进行设置
  14. AnnotationAttributes enableAspectJAutoProxy =
  15. AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
  16. if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
  17. AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
  18. }
  19. if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
  20. AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
  21. }
  22. }
  23. }

AnnotationAwareAspectJAutoProxyCreator继承图

image.png

类分析和打断点

主要方法在接口里面,在BeanFactoryAware的setBeanFactory和InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation以及BeanPostProcessor的postProcessAfterInitialization
具体的实现在这四个类的方法里面,可以打上断点看看看

AnnotationAwareAspectJAutoProxyCreator组件

流程:如何创建这个组件

26.spring源码之AOP - 图2

  1. 为什么从这里开始,因为AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor
  2. 所有的BeanPostProcessor分为三个等级PriorityOrdered/Ordered/regular
  3. 这里属于Ordered
    1. 进入到beanFactory.getBean的创建Bean流程
  4. getBean在ioc章节已经有流程图了https://www.processon.com/diagraming/607ada88f346fb647a594af3,继续温习一遍
  5. 下面是通用的流程

    1. beanFactory{
    2. 方法getBean{}
    3. 方法createBean{
    4. //Give BeanPostProcessors a chance to return a proxy instead of the target bean instance
    5. //我们自定义的类在这里就会被组件拿去增强
    6. //具体就是遍历后置处理器,对方法进行增强,如果得到了,就return,如果得不到代理对象才会进入doCreateBean来创建
    7. resolveBeforeInstantiation();
    8. doCreateBean();
    9. }
    10. ....最终进入下面这个方法
    11. 方法doCreateBean{
    12. //1创建对象
    13. instanceWrapper = createBeanInstance(beanName, mbd, args);
    14. //2.1初始化实例-1详见IOC流程图
    15. populateBean();
    16. //2.2初始化实例-2
    17. initializeBean();
    18. }
    19. 方法initializeBean{
    20. //2.2.1回调BeanNameAware/BeanClassLoaderAware/BeanFactoryAware set对应的值
    21. invokeAwareMethods();
    22. //2.2.2遍历后置处理器增强
    23. applyBeanPostProcessorsBeforeInitialization();
    24. //2.2.3
    25. invokeInitMethods();
    26. //2.2.4遍历后置处理器增强
    27. applyBeanPostProcessorsAfterInitialization();
    28. }
    29. 方法resolveBeforeInstantiation{
    30. //组件在这里就发挥作用了
    31. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    32. if (bean != null) {
    33. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    34. }
    35. }
    36. }

    流程:这个组件的使用(其他地方用它)

  1. 故事从16finishBeanFactoryInitialization开始
  2. 这里就是初始化一些spring自定义的普通组件和我们的配置类,组件了.让我们看看有谁进来了?进入到组件的postProcessAfterInitialization方法里面呢?
    1. EventListenerMethodProcessor
    2. DefaultEventListenerFactory
    3. 自定义的MainConfigOfAOP
    4. 自定义的MathCalculator
    5. 自定义的LogAspects

image.png
image.png

细节分析-组件

看一下大致流程
组件MathCalculator的调用顺序来看大致流程

16finishBeanFactoryInitialization
BeanFactory#createBean
resolveBeforeInstantiation生成代理对象(遍历所有后置处理器)
image.png

第一次进入postProcessBeforeInstantiation

  1. @Override
  2. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
  3. Object cacheKey = getCacheKey(beanClass, beanName);
  4. if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
  5. if (this.advisedBeans.containsKey(cacheKey)) {
  6. return null;
  7. }
  8. //shouldSkip就会去找潜在的adivce增强器
  9. if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
  10. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  11. return null;
  12. }
  13. }
  14. // Create proxy here if we have a custom TargetSource.
  15. // Suppresses unnecessary default instantiation of the target bean:
  16. // The TargetSource will handle target instances in a custom fashion.
  17. if (beanName != null) {
  18. TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
  19. if (targetSource != null) {
  20. this.targetSourcedBeans.add(beanName);
  21. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  22. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
  23. this.proxyTypes.put(cacheKey, proxy.getClass());
  24. return proxy;
  25. }
  26. }
  27. return null;
  28. }

返回null,然后就要进入正常的doCreateBean流程创建Bean
然后进入applyBeanPostProcessorsAfterInitialization(遍历BeanPostProcessor)

接着组件的postProcessAfterInitialization

流程比较多先进入wrapIfNecessary

  1. //核心逻辑都在2,会返回代理对象
  2. protected Object wrapIfNecessary{
  3. //1这个详细看看
  4. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  5. //2这个比较复杂!
  6. Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  7. return proxy;//最终这里返回了cglib代理对象
  8. }
  9. getAdvicesAndAdvisorsForBean就是调用findEligibleAdvisors
  10. //1.1找到所有需要增强的切面方法,包装成List<Advisor>
  11. //找到所有的切面方法,然后去匹配,最终得到当前方法适配的
  12. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  13. //找到所有
  14. List<Advisor> candidateAdvisors = findCandidateAdvisors();
  15. //匹配
  16. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  17. //AspectJ的话list开头加一个ExposeInvocationInterceptor
  18. extendAdvisors(eligibleAdvisors);
  19. //排序
  20. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  21. return eligibleAdvisors;
  22. }
  23. //1.1.1
  24. protected List<Advisor> findCandidateAdvisors() {
  25. // Add all the Spring advisors found according to superclass rules.
  26. List<Advisor> advisors = super.findCandidateAdvisors();空
  27. // Build Advisors for all AspectJ aspects in the bean factory.
  28. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());//真正逻辑
  29. return advisors;
  30. }
  31. //1.1.1.1遍历所有的Aspect,把每个Aspect的InstantiationModelAwarePointcutAdvisorImpl放在list里面
  32. public List<Advisor> buildAspectJAdvisors() {
  33. List<Advisor> advisors = new LinkedList<Advisor>();//这数据类型有点意思
  34. for (String aspectName : aspectNames) {
  35. List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);//进来的时候缓存就有,直接取出来
  36. if (cachedAdvisors != null) {
  37. advisors.addAll(cachedAdvisors);
  38. }
  39. else {
  40. MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
  41. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  42. }
  43. }
  44. return advisors;
  45. }
  46. //1.1.2
  47. protected List<Advisor> findAdvisorsThatCanApply(
  48. List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
  49. ProxyCreationContext.setCurrentProxiedBeanName(beanName);
  50. try {
  51. return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);真正逻辑
  52. }
  53. finally {
  54. ProxyCreationContext.setCurrentProxiedBeanName(null);
  55. }
  56. }
  57. public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  58. List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
  59. boolean hasIntroductions = !eligibleAdvisors.isEmpty();
  60. for (Advisor candidate : candidateAdvisors) {
  61. if (canApply(candidate, clazz, hasIntroductions)) {
  62. eligibleAdvisors.add(candidate);
  63. }
  64. }
  65. return eligibleAdvisors;
  66. }
  67. //第一个参数就是InstantiationModelAwarePointcutAdvisorImpl
  68. public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
  69. else if (advisor instanceof PointcutAdvisor) {
  70. PointcutAdvisor pca = (PointcutAdvisor) advisor;
  71. return canApply(pca.getPointcut(), targetClass, hasIntroductions);
  72. }
  73. }
  74. //第一个参数是InstantiationModelAwarePointcutAdvisorImpl的AspectJExpressionPointcut
  75. //真正逻辑在introductionAwareMethodMatcher.matches
  76. public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  77. MethodMatcher methodMatcher = pc.getMethodMatcher();//就是本身
  78. IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
  79. if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
  80. introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
  81. }
  82. Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
  83. classes.add(targetClass);
  84. for (Class<?> clazz : classes) {
  85. Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
  86. //只要有一个方法匹配就是true
  87. for (Method method : methods) {
  88. if ((introductionAwareMethodMatcher != null &&
  89. introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
  90. methodMatcher.matches(method, targetClass)) {
  91. return true;
  92. }
  93. }
  94. }
  95. return false;
  96. }
  97. @Override
  98. public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
  99. Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
  100. ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);
  101. // Special handling for this, target, @this, @target, @annotation
  102. // in Spring - we can optimize since we know we have exactly this class,
  103. // and there will never be matching subclass at runtime.
  104. if (shadowMatch.alwaysMatches()) {
  105. return true;
  106. }
  107. }

具体是这样的
image.png

image.png
继续分析之前没看到的

  1. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

具体

  1. //Create an AOP proxy for the given bean.
  2. protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
  3. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  4. proxyFactory.addAdvisors(advisors);//切面类
  5. proxyFactory.setTargetSource(targetSource);//需要增强的类
  6. customizeProxyFactory(proxyFactory);//空的,等子类实现
  7. return proxyFactory.getProxy(getProxyClassLoader());//逻辑在这里
  8. }
  9. public Object getProxy(ClassLoader classLoader) {
  10. return createAopProxy().getProxy(classLoader);
  11. }
  12. protected final synchronized AopProxy createAopProxy() {
  13. if (!this.active) {
  14. activate();
  15. }
  16. return getAopProxyFactory().createAopProxy(this);
  17. }
  18. //Create an {@link AopProxy} for the given AOP configuration.工厂模式,根据代理的情况(配置),创建不同的代理对象
  19. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  20. if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
  21. Class<?> targetClass = config.getTargetClass();
  22. if (targetClass == null) {
  23. throw new AopConfigException("TargetSource cannot determine target class: " +
  24. "Either an interface or a target is required for proxy creation.");
  25. }
  26. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
  27. return new JdkDynamicAopProxy(config);
  28. }
  29. return new ObjenesisCglibAopProxy(config);
  30. }
  31. else {
  32. return new JdkDynamicAopProxy(config);
  33. }
  34. }

针对工厂的注释
image.png
现在就看看cglib怎么生成代理对象吧

  1. @Override
  2. public Object getProxy(ClassLoader classLoader) {
  3. try {
  4. Class<?> proxySuperClass = rootClass;
  5. if (ClassUtils.isCglibProxyClass(rootClass)) {
  6. proxySuperClass = rootClass.getSuperclass();
  7. Class<?>[] additionalInterfaces = rootClass.getInterfaces();
  8. for (Class<?> additionalInterface : additionalInterfaces) {
  9. this.advised.addInterface(additionalInterface);
  10. }
  11. }
  12. // Validate the class, writing log messages as necessary.
  13. validateClassIfNecessary(proxySuperClass, classLoader);
  14. // Configure CGLIB Enhancer...
  15. Enhancer enhancer = createEnhancer();
  16. if (classLoader != null) {
  17. enhancer.setClassLoader(classLoader);
  18. if (classLoader instanceof SmartClassLoader &&
  19. ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
  20. enhancer.setUseCache(false);
  21. }
  22. }
  23. enhancer.setSuperclass(proxySuperClass);
  24. enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
  25. enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
  26. enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
  27. //这里貌似是核心逻辑先记录一下
  28. Callback[] callbacks = getCallbacks(rootClass);
  29. Class<?>[] types = new Class<?>[callbacks.length];
  30. for (int x = 0; x < types.length; x++) {
  31. types[x] = callbacks[x].getClass();
  32. }
  33. // fixedInterceptorMap only populated at this point, after getCallbacks call above
  34. enhancer.setCallbackFilter(new ProxyCallbackFilter(
  35. this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
  36. enhancer.setCallbackTypes(types);
  37. // Generate the proxy class and create a proxy instance.
  38. return createProxyClassAndInstance(enhancer, callbacks);
  39. }
  40. catch (CodeGenerationException ex) {
  41. throw new AopConfigException("Could not generate CGLIB subclass of class [" +
  42. this.advised.getTargetClass() + "]: " +
  43. "Common causes of this problem include using a final class or a non-visible class",
  44. ex);
  45. }
  46. catch (IllegalArgumentException ex) {
  47. throw new AopConfigException("Could not generate CGLIB subclass of class [" +
  48. this.advised.getTargetClass() + "]: " +
  49. "Common causes of this problem include using a final class or a non-visible class",
  50. ex);
  51. }
  52. catch (Throwable ex) {
  53. // TargetSource.getTarget() failed
  54. throw new AopConfigException("Unexpected AOP exception", ex);
  55. }
  56. }
  57. private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
  58. // Parameters used for optimization choices...
  59. boolean exposeProxy = this.advised.isExposeProxy();
  60. boolean isFrozen = this.advised.isFrozen();
  61. boolean isStatic = this.advised.getTargetSource().isStatic();
  62. // Choose an "aop" interceptor (used for AOP calls).
  63. Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
  64. // Choose a "straight to target" interceptor. (used for calls that are
  65. // unadvised but can return this). May be required to expose the proxy.
  66. Callback targetInterceptor;
  67. if (exposeProxy) {
  68. targetInterceptor = isStatic ?
  69. new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
  70. new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
  71. }
  72. else {
  73. targetInterceptor = isStatic ?
  74. new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
  75. new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
  76. }
  77. // Choose a "direct to target" dispatcher (used for
  78. // unadvised calls to static targets that cannot return this).
  79. Callback targetDispatcher = isStatic ?
  80. new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
  81. Callback[] mainCallbacks = new Callback[] {
  82. aopInterceptor, // for normal advice
  83. targetInterceptor, // invoke target without considering advice, if optimized
  84. new SerializableNoOp(), // no override for methods mapped to this
  85. targetDispatcher, this.advisedDispatcher,
  86. new EqualsInterceptor(this.advised),
  87. new HashCodeInterceptor(this.advised)
  88. };
  89. Callback[] callbacks;
  90. // If the target is a static one and the advice chain is frozen,
  91. // then we can make some optimizations by sending the AOP calls
  92. // direct to the target using the fixed chain for that method.
  93. if (isStatic && isFrozen) {
  94. Method[] methods = rootClass.getMethods();
  95. Callback[] fixedCallbacks = new Callback[methods.length];
  96. this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
  97. // TODO: small memory optimization here (can skip creation for methods with no advice)
  98. for (int x = 0; x < methods.length; x++) {
  99. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
  100. fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
  101. chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
  102. this.fixedInterceptorMap.put(methods[x].toString(), x);
  103. }
  104. // Now copy both the callbacks from mainCallbacks
  105. // and fixedCallbacks into the callbacks array.
  106. callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
  107. System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
  108. System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
  109. this.fixedInterceptorOffset = mainCallbacks.length;
  110. }
  111. else {
  112. callbacks = mainCallbacks;
  113. }
  114. return callbacks;
  115. }

image.png得到这些
最终来生成

  1. protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
  2. Class<?> proxyClass = enhancer.createClass();
  3. Object proxyInstance = null;
  4. if (objenesis.isWorthTrying()) {
  5. try {
  6. proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
  7. }
  8. catch (Throwable ex) {
  9. logger.debug("Unable to instantiate proxy using Objenesis, " +
  10. "falling back to regular proxy construction", ex);
  11. }
  12. }
  13. if (proxyInstance == null) {
  14. // Regular instantiation via default constructor...
  15. try {
  16. proxyInstance = (this.constructorArgs != null ?
  17. proxyClass.getConstructor(this.constructorArgTypes).newInstance(this.constructorArgs) :
  18. proxyClass.newInstance());
  19. }
  20. catch (Throwable ex) {
  21. throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
  22. "and regular proxy instantiation via default constructor fails as well", ex);
  23. }
  24. }
  25. ((Factory) proxyInstance).setCallbacks(callbacks);
  26. return proxyInstance;
  27. }

最终得到image.png

流程:真正运作

主要就是把
image.png
转换成
image.png
可以看看转换的逻辑

  1. public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
  2. List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
  3. Advice advice = advisor.getAdvice();//这个还不一样
  4. if (advice instanceof MethodInterceptor) {
  5. interceptors.add((MethodInterceptor) advice);
  6. }
  7. for (AdvisorAdapter adapter : this.adapters) {
  8. if (adapter.supportsAdvice(advice)) {
  9. interceptors.add(adapter.getInterceptor(advisor));
  10. }
  11. }
  12. if (interceptors.isEmpty()) {
  13. throw new UnknownAdviceTypeException(advisor.getAdvice());
  14. }
  15. return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
  16. }

实际运作

  1. public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  2. Object oldProxy = null;
  3. boolean setProxyContext = false;
  4. Class<?> targetClass = null;
  5. Object target = null;
  6. try {
  7. if (this.advised.exposeProxy) {
  8. // Make invocation available if necessary.
  9. oldProxy = AopContext.setCurrentProxy(proxy);
  10. setProxyContext = true;
  11. }
  12. // May be null. Get as late as possible to minimize the time we
  13. // "own" the target, in case it comes from a pool...
  14. target = getTarget();
  15. if (target != null) {
  16. targetClass = target.getClass();
  17. }
  18. //真正逻辑
  19. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  20. Object retVal;
  21. // Check whether we only have one InvokerInterceptor: that is,
  22. // no real advice, but just reflective invocation of the target.
  23. if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
  24. // We can skip creating a MethodInvocation: just invoke the target directly.
  25. // Note that the final invoker must be an InvokerInterceptor, so we know
  26. // it does nothing but a reflective operation on the target, and no hot
  27. // swapping or fancy proxying.
  28. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
  29. retVal = methodProxy.invoke(target, argsToUse);
  30. }
  31. else {
  32. // We need to create a method invocation...
  33. //真正逻辑
  34. retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
  35. }
  36. retVal = processReturnType(proxy, target, method, retVal);
  37. return retVal;
  38. }
  39. finally {
  40. if (target != null) {
  41. releaseTarget(target);
  42. }
  43. if (setProxyContext) {
  44. // Restore old proxy.
  45. AopContext.setCurrentProxy(oldProxy);
  46. }
  47. }
  48. }
  1. public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
  2. MethodCacheKey cacheKey = new MethodCacheKey(method);
  3. List<Object> cached = this.methodCache.get(cacheKey);
  4. if (cached == null) {
  5. cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
  6. this, method, targetClass);
  7. this.methodCache.put(cacheKey, cached);
  8. }
  9. return cached;
  10. }
  1. @Override
  2. public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
  3. Advised config, Method method, Class<?> targetClass) {
  4. // This is somewhat tricky... We have to process introductions first,
  5. // but we need to preserve order in the ultimate list.
  6. List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
  7. Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
  8. boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
  9. AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
  10. for (Advisor advisor : config.getAdvisors()) {
  11. if (advisor instanceof PointcutAdvisor) {
  12. // Add it conditionally.
  13. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
  14. if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
  15. //真正逻辑
  16. MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
  17. MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
  18. if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
  19. if (mm.isRuntime()) {
  20. // Creating a new object instance in the getInterceptors() method
  21. // isn't a problem as we normally cache created chains.
  22. for (MethodInterceptor interceptor : interceptors) {
  23. interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
  24. }
  25. }
  26. else {
  27. interceptorList.addAll(Arrays.asList(interceptors));
  28. }
  29. }
  30. }
  31. }
  32. else if (advisor instanceof IntroductionAdvisor) {
  33. IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
  34. if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
  35. Interceptor[] interceptors = registry.getInterceptors(advisor);
  36. interceptorList.addAll(Arrays.asList(interceptors));
  37. }
  38. }
  39. else {
  40. Interceptor[] interceptors = registry.getInterceptors(advisor);
  41. interceptorList.addAll(Arrays.asList(interceptors));
  42. }
  43. }
  44. return interceptorList;
  45. }
  46. @Override
  47. public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
  48. List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
  49. Advice advice = advisor.getAdvice();//取出来,进行封装
  50. if (advice instanceof MethodInterceptor) {//直接塞进去
  51. interceptors.add((MethodInterceptor) advice);
  52. }
  53. for (AdvisorAdapter adapter : this.adapters) {//适配一下塞进去
  54. if (adapter.supportsAdvice(advice)) {
  55. interceptors.add(adapter.getInterceptor(advisor));
  56. }
  57. }
  58. if (interceptors.isEmpty()) {
  59. throw new UnknownAdviceTypeException(advisor.getAdvice());
  60. }
  61. return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
  62. }

image.pngconfig.getAdvisors()得到
image.png这两个就是前面生成的
image.png
遍历这5个,利用适配器封装为MethodInterceptor[]
最终转换成的样子,主要看关键方法,以及实现的接口

  1. public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
  2. implements MethodInterceptor, AfterAdvice, Serializable {
  3. @Override
  4. public boolean isAfterAdvice() {
  5. return true;
  6. }
  7. @Override
  8. public Object invoke(MethodInvocation mi) throws Throwable {
  9. try {
  10. return mi.proceed();
  11. }
  12. catch (Throwable ex) {
  13. if (shouldInvokeOnThrowing(ex)) {
  14. //调用业务逻辑
  15. invokeAdviceMethod(getJoinPointMatch(), null, ex);
  16. }
  17. throw ex;
  18. }
  19. }
  20. /**
  21. * In AspectJ semantics, after throwing advice that specifies a throwing clause
  22. * is only invoked if the thrown exception is a subtype of the given throwing type.
  23. */
  24. private boolean shouldInvokeOnThrowing(Throwable ex) {
  25. return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
  26. }
  27. }
  28. public class AspectJAfterAdvice extends AbstractAspectJAdvice
  29. implements MethodInterceptor, AfterAdvice, Serializable {
  30. @Override
  31. public Object invoke(MethodInvocation mi) throws Throwable {
  32. try {
  33. return mi.proceed();
  34. }
  35. finally {
  36. invokeAdviceMethod(getJoinPointMatch(), null, null);
  37. }
  38. }
  39. @Override
  40. public boolean isAfterAdvice() {
  41. return true;
  42. }
  43. }
  1. public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
  2. private MethodBeforeAdvice advice;
  3. /**
  4. * Create a new MethodBeforeAdviceInterceptor for the given advice.
  5. * @param advice the MethodBeforeAdvice to wrap
  6. */
  7. public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
  8. Assert.notNull(advice, "Advice must not be null");
  9. this.advice = advice;
  10. }
  11. @Override
  12. public Object invoke(MethodInvocation mi) throws Throwable {
  13. this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
  14. return mi.proceed();
  15. }
  16. }
  17. public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
  18. private final AfterReturningAdvice advice;
  19. /**
  20. * Create a new AfterReturningAdviceInterceptor for the given advice.
  21. * @param advice the AfterReturningAdvice to wrap
  22. */
  23. public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
  24. Assert.notNull(advice, "Advice must not be null");
  25. this.advice = advice;
  26. }
  27. @Override
  28. public Object invoke(MethodInvocation mi) throws Throwable {
  29. Object retVal = mi.proceed();
  30. this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
  31. return retVal;
  32. }
  33. }

看看CglibMethodInvocation#proceed逻辑
image.png

  1. @Override
  2. public Object proceed() throws Throwable {
  3. // We start with an index of -1 and increment early.
  4. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
  5. return invokeJoinpoint();
  6. }
  7. Object interceptorOrInterceptionAdvice =
  8. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
  9. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
  10. // Evaluate dynamic method matcher here: static part will already have
  11. // been evaluated and found to match.
  12. InterceptorAndDynamicMethodMatcher dm =
  13. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
  14. if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
  15. return dm.interceptor.invoke(this);
  16. }
  17. else {
  18. // Dynamic matching failed.
  19. // Skip this interceptor and invoke the next in the chain.
  20. return proceed();
  21. }
  22. }
  23. else {
  24. // It's an interceptor, so we just invoke it: The pointcut will have
  25. // been evaluated statically before this object was constructed.
  26. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  27. }
  28. }

第一次进来ExposeInvocationInterceptor,没做什么内容就第二个了
第二个AspectJAfterThrowingAdvice,调用一下,捕捉异常,执行切面异常逻辑
第三个AfterReturningAdviceInterceptor,{1,调用下一个,执行切面afterReturning逻辑}
第四个AspectJAfterAdvice,{调用下一个,然后finally执行切面after逻辑}
第五个是MethodBeforeAdviceInterceptor,{调用切面before逻辑,执行下一个}
执行完是4了,proceed就执行目标真正逻辑
执行After逻辑
正常的话执行AfterReturning逻辑,异常执行AfterThrowing逻辑

总结一下

image.png

声明式事务

image.png
service->
doCreateBean
initializeBean
applyBeanPostProcessorsAfterInitialization
进入到AbstractAutoProxyCreator(InfrastructureAdvisorAutoProxyCreator)#postProcessAfterInitialization
wrapIfNecessary

  1. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  2. if (specificInterceptors != DO_NOT_PROXY) {
  3. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  4. Object proxy = createProxy(
  5. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  6. this.proxyTypes.put(cacheKey, proxy.getClass());
  7. return proxy;
  8. }

拦截器是谁?
BeanFactoryTransactionAttributeSourceAdvisor
封装成Advisor放在ProxyFactory
创建的cglibAopProxy生成代理对象


执行的时候代理对象
用TransactionInterceptor拦截目标对象
DynamicAdvisedInterceptor#intercept
{new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}
TransactionInterceptor#invoke
#invokeWithinTransaction

  1. protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
  2. throws Throwable {
  3. // If the transaction attribute is null, the method is non-transactional.注解里面的属性之类的
  4. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
  5. //这个就是我们自己配置的,见下图
  6. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
  7. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  8. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  9. // Standard transaction demarcation with getTransaction and commit/rollback calls.
  10. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
  11. Object retVal = null;
  12. try {
  13. // This is an around advice: Invoke the next interceptor in the chain.
  14. // This will normally result in a target object being invoked.
  15. retVal = invocation.proceedWithInvocation();//调用真正的方法
  16. }
  17. catch (Throwable ex) {
  18. // target invocation exception
  19. completeTransactionAfterThrowing(txInfo, ex);//方法异常了就回滚
  20. throw ex;
  21. }
  22. finally {
  23. cleanupTransactionInfo(txInfo);
  24. }
  25. commitTransactionAfterReturning(txInfo);//方法正常返回结束了就提交事务
  26. return retVal;
  27. }
  28. else {
  29. // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
  30. ...回滚
  31. }

image.png