使用Spring AOP

添加注解@EnableAspectJAutoProxy

  1. @EnableAspectJAutoProxy

添加pom

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-aop</artifactId>
  4. <version>5.2.2.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.aspectj</groupId>
  8. <artifactId>aspectjrt</artifactId>
  9. <version>1.8.9</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.aspectj</groupId>
  13. <artifactId>aspectjweaver</artifactId>
  14. <version>1.8.9</version>
  15. </dependency>

添加 Aspect

  1. @Component
  2. @Aspect
  3. public class TestAop {
  4. @Before("pointCut()")
  5. public void methodBefore() {
  6. System.out.println("方法调用前1");
  7. }
  8. // @Pointcut("execution(* com.mkb.service.UserService.*.*(..))")
  9. @Pointcut("execution(public * *(..))")
  10. public void pointCut() {
  11. }
  12. @Around("pointCut()")
  13. public Object processMethod(ProceedingJoinPoint jp) throws Throwable {
  14. System.out.println("方法调用前processMethod");
  15. return jp.proceed();
  16. }
  17. @After("pointCut()")
  18. public void methodAfter() {
  19. System.out.println("方法调用后1");
  20. }
  21. }

要学习Spring AOP 最好先把spring ioc学习清楚

在ioc中我们知道springbean是怎么初始化的,下面是初始化中的一个方法

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. BeanWrapper instanceWrapper = null;
  5. if (mbd.isSingleton()) {
  6. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  7. }
  8. if (instanceWrapper == null) {
  9. instanceWrapper = createBeanInstance(beanName, mbd, args);
  10. }
  11. final Object bean = instanceWrapper.getWrappedInstance();
  12. Class<?> beanType = instanceWrapper.getWrappedClass();
  13. if (beanType != NullBean.class) {
  14. mbd.resolvedTargetType = beanType;
  15. }
  16. // Allow post-processors to modify the merged bean definition.
  17. synchronized (mbd.postProcessingLock) {
  18. if (!mbd.postProcessed) {
  19. try {
  20. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  21. }
  22. catch (Throwable ex) {
  23. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  24. "Post-processing of merged bean definition failed", ex);
  25. }
  26. mbd.postProcessed = true;
  27. }
  28. }
  29. // Eagerly cache singletons to be able to resolve circular references
  30. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  31. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  32. isSingletonCurrentlyInCreation(beanName));
  33. if (earlySingletonExposure) {
  34. if (logger.isTraceEnabled()) {
  35. logger.trace("Eagerly caching bean '" + beanName +
  36. "' to allow for resolving potential circular references");
  37. }
  38. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  39. }
  40. // Initialize the bean instance.
  41. Object exposedObject = bean;
  42. try {
  43. populateBean(beanName, mbd, instanceWrapper);
  44. exposedObject = initializeBean(beanName, exposedObject, mbd);
  45. }
  46. catch (Throwable ex) {
  47. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  48. throw (BeanCreationException) ex;
  49. }
  50. else {
  51. throw new BeanCreationException(
  52. mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  53. }
  54. }
  55. if (earlySingletonExposure) {
  56. Object earlySingletonReference = getSingleton(beanName, false);
  57. if (earlySingletonReference != null) {
  58. if (exposedObject == bean) {
  59. exposedObject = earlySingletonReference;
  60. }
  61. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  62. String[] dependentBeans = getDependentBeans(beanName);
  63. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
  64. for (String dependentBean : dependentBeans) {
  65. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  66. actualDependentBeans.add(dependentBean);
  67. }
  68. }
  69. if (!actualDependentBeans.isEmpty()) {
  70. throw new BeanCurrentlyInCreationException(beanName,
  71. "Bean with name '" + beanName + "' has been injected into other beans [" +
  72. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  73. "] in its raw version as part of a circular reference, but has eventually been " +
  74. "wrapped. This means that said other beans do not use the final version of the " +
  75. "bean. This is often the result of over-eager type matching - consider using " +
  76. "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
  77. }
  78. }
  79. }
  80. }
  81. // Register bean as disposable.
  82. try {
  83. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  84. }
  85. catch (BeanDefinitionValidationException ex) {
  86. throw new BeanCreationException(
  87. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  88. }
  89. return exposedObject;
  90. }

就是 instanceWrapper = createBeanInstance(beanName, mbd, args); 这个方法实例化了bean对象,这个获取的是原生的bean,并没有产生代理,那么代理肯定是在后面的代码中初始化完成。

进入exposedObject = initializeBean(beanName, exposedObject, mbd);

  1. protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
  2. if (System.getSecurityManager() != null) {
  3. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  4. invokeAwareMethods(beanName, bean);
  5. return null;
  6. }, getAccessControlContext());
  7. }
  8. else {
  9. invokeAwareMethods(beanName, bean);
  10. }
  11. Object wrappedBean = bean;
  12. if (mbd == null || !mbd.isSynthetic()) {
  13. //前置处理器
  14. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  15. }
  16. try {
  17. invokeInitMethods(beanName, wrappedBean, mbd);
  18. }
  19. catch (Throwable ex) {
  20. throw new BeanCreationException(
  21. (mbd != null ? mbd.getResourceDescription() : null),
  22. beanName, "Invocation of init method failed", ex);
  23. }
  24. if (mbd == null || !mbd.isSynthetic()) {
  25. //后置处理器
  26. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  27. }
  28. return wrappedBean;
  29. }

继续进入wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

  1. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  2. throws BeansException {
  3. Object result = existingBean;
  4. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  5. Object current = processor.postProcessAfterInitialization(result, beanName);
  6. if (current == null) {
  7. return result;
  8. }
  9. result = current;
  10. }
  11. return result;
  12. }

Object current = processor.postProcessAfterInitialization(result, beanName); 这个后置处理器有很多实现,只有添加了 @EnableAspectJAutoProxy 这个注解才会初始化AbstractAutoProxyCreator 这个处理器来产生代理对象

继续进入postProcessAfterInitialization 找到 AbstractAutoProxyCreator实现

继续进入 wrapIfNecessary

  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  2. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  3. return bean;
  4. }
  5. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  6. return bean;
  7. }
  8. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  9. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  10. return bean;
  11. }
  12. // Create proxy if we have advice.
  13. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  14. if (specificInterceptors != DO_NOT_PROXY) {
  15. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  16. Object proxy = createProxy(
  17. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  18. this.proxyTypes.put(cacheKey, proxy.getClass());
  19. return proxy;
  20. }
  21. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  22. return bean;
  23. }

继续进入Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
  3. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
  4. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
  5. }
  6. ProxyFactory proxyFactory = new ProxyFactory();
  7. proxyFactory.copyFrom(this);
  8. if (!proxyFactory.isProxyTargetClass()) {
  9. if (shouldProxyTargetClass(beanClass, beanName)) {
  10. proxyFactory.setProxyTargetClass(true);
  11. }
  12. else {
  13. evaluateProxyInterfaces(beanClass, proxyFactory);
  14. }
  15. }
  16. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  17. proxyFactory.addAdvisors(advisors);
  18. proxyFactory.setTargetSource(targetSource);
  19. customizeProxyFactory(proxyFactory);
  20. proxyFactory.setFrozen(this.freezeProxy);
  21. if (advisorsPreFiltered()) {
  22. proxyFactory.setPreFiltered(true);
  23. }
  24. return proxyFactory.getProxy(getProxyClassLoader());
  25. }

继续进入proxyFactory.getProxy(getProxyClassLoader());

  1. public Object getProxy(@Nullable ClassLoader classLoader) {
  2. return createAopProxy().getProxy(classLoader);
  3. }

getProxy 这个方法可能有两个实现
image.png
可以看到取决于我们再注入 @EnableAspectJAutoProxy 注解的时候使用了什么代理,CGlib 还是 jdk自带的根据我们的选择来通过不同的方法实现代理对象。

总结:spring内部实现aop就是,在原生的bean产生后,通过后置处理器来生成一个新的代理bean存放在缓存中。然后调用代理类的方法,就是会调用handlerr的invoke,这样就实现了动态代理,也是aop的实现原理。