Spring AOP

AOP面向切面编程

    aop专门用来处理系统中分布于各个模块中交叉关注点的问题,常常用来处理例如:安全检查、缓存、对象池管理等。

    即:例如银行系统有 流程a 验证用户->查询余额->结束;流程b 验证用户->取款->结束。a和b中都有验证用户这一公共模块,那么就可以把验证用户单独取出来,这就是aop。在写代码的时候,只考虑主流程,而不用考虑哪些不是很重要的流程。

先写一个例子

目标类

@Component
public class Calcutor {

    public int div(int i, int j) {
        System.out.println("目标方法开始运行");
        return i/j;
    }
}

切面类

/**
 * @Description: 日志切面类
 * 日志切面类可以动态感知到方法的运行
 * 通知方法:
 *      前置通知(@Before):目标方法运行之前
 *      后置通知:目标方法运行之后
 *      返回通知:目标方法正常返回之后运行(目标方法异常不允许)
 *      异常通知:目标方法出现异常后运行
 *      环绕通知:动态代理,需要手动执行joinPoint.procced()
 *
 * 可以通过joinPoint 获取方法信息
 */
@Aspect
public class LogAspects {
    /**
     * 声明需要切入的目标
     * execution
     * 完整写法  execution(public int com.zxl.aop.bean.Calcutor.div(int, int))
     * 指定类中任意方法  execution(public int com.zxl.aop.bean.Calcutor.*(..))
     */
    @Pointcut("execution(public int com.zxl.aop.bean.Calcutor.*(..))")
    public void pointCut() {

    }
    /**
     * 代表在目标方法之前切入,并指定方法
     */
//    @Before("execution(public int com.zxl.aop.bean.Calcutor.*(..))")
    @Before("pointCut()")
//    public void logStart() {
//        System.out.println("@Before--方法之前--->");
//    }
    public void logStart(JoinPoint joinPoint) {
        System.out.println("@Before--方法之前--->方法名" +joinPoint.getSignature().getName()
                + "参数-->" + Arrays.asList(joinPoint.getArgs()));
    }

    /**
     * 代表在目标方法之后切入,并指定方法
     */
    @After("pointCut()")
    public void logEnd() {
        System.out.println("@After--方法之后--->");
    }

    /**
     * 目标方法正常返回之后
     */
    @AfterReturning(value = "pointCut()", returning = "obj")
//    public void logReturn() {
        System.out.println("@AfterReturning--方法正常返回--->");
    }
    public void logReturn(Object obj) {
        System.out.println("@AfterReturning--方法正常返回--->"+ obj);
    }

    /**
     * 目标方法异常之后
     */
//    @AfterThrowing("pointCut()")
//    public void logException() {
//        System.out.println("@AfterThrowing--方法运行异常--->");
//    }
    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public void logException(Exception exception) {
        System.out.println("@AfterThrowing--方法运行异常--->" + exception.getMessage());
    }

    /**
     * 环绕
     * @param joinPoint
     */
    @Around("pointCut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 还在before之前
        System.out.println(" @Around执行目标方法之前--->");
        // 动态代理,通过反射调用目标方法
        Object proceed = joinPoint.proceed();
        System.out.println(" @Around执行目标方法之后--->");
        return proceed;
    }
}

AnnotationAwareAspectJAutoProxyCreator   AOP工具类创建流程

  • register()传入配置类,准备创建ioc容器
  • 注册配置类,调用refresh()刷新创建容器
  • registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建(主要是创建AnnotationAwareAspectJAutoProxyCreator)
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 获取所有的BeanPostProcessor
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
 
		 // 先注册实现了PriorityOrdered的BeanPostProcessor,添加到beanfactory
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
 
		// 再注册实现了Ordered的BeanPostProcessor,添加到beanfactory
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);
 
		// 最后注册剩余的BeanPostProcessor,添加到beanfactory
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);
	}
  • 跟进去beanFactory.getBean(ppName, BeanPostProcessor.class),一直跟到doGetBean
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				
	}

 再跟进去createBean

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		try {
            //去创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
	}

再跟进 doCreateBean(beanName, mbdToUse, args);

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
 
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            // 利用工厂方法或者对象的构造器创建出Bean实例;
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		
	
		Object exposedObject = bean;
		try {
            // Bean属性赋值.应用Bean属性的值;为属性利用setter方法等进行赋值
            // 赋值拿到后置处理器,执行后置处理器的方法
			populateBean(beanName, mbd, instanceWrapper);
             //Bean初始化
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		return exposedObject;
	}
  • 到此AnnotationAwareAspectJAutoProxyCreator就创建完了,其实他跟普通的bean创建流程一样,只不过是创建的时机不同。

 

创建增强bean的流程

  • refresh方法中的finishBeanFactoryInitialization(beanFactory)方法
  • 遍历获取容器中所有bean,如果获取不到就进行创建
	public void preInstantiateSingletons() throws BeansException {
		// 上面的代码省略
		for (String beanName : beanNames) {
            // 获取bean的定义信息
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 判断是否懒加载、是否单实例、是否抽象的
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
					
						}
					}
				}
				else {
                    // 都不是,则获取bean
					getBean(beanName);
				}
			}
    // 将创建的Bean添加到缓存中singletonObjects,其实就是放进了map中
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
		}
	}
  • 跟进getBean一直到doGetBean方法,再进入createBean方法
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		try {
			// 让BeanPostProcessor先拦截返回代理对象;
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		
		try {
            // 开始创建实例
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
	}
  • 进入resolveBeforeInstantiation(beanName, mbdToUse)方法
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
                    //前置处理器
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
// 最终返回null
		return bean;
	}
  • 再次跟进去doCreateBean(beanName, mbdToUse, args);
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
 
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            // 利用工厂方法或者对象的构造器创建出Bean实例;
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		
	
		Object exposedObject = bean;
		try {
            // Bean属性赋值.应用Bean属性的值;为属性利用setter方法等进行赋值
            // 赋值拿到后置处理器,执行后置处理器的方法
			populateBean(beanName, mbd, instanceWrapper);
             //Bean初始化
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		return exposedObject;
	}
  • 跟进去initializeBean(beanName, exposedObject, mbd);
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
 
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // 执行前置处理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
 
		try {
            // 执行初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            // 执行后置处理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
 
		return wrappedBean;
	}
  • 跟进去applyBeanPostProcessorsAfterInitialization,再跟进去postProcessAfterInitialization,再跟进去AbstractAutoProxyCreator类的postProcessAfterInitialization。
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }
  • 如果是切面类。那么就继续往下走wrapIfNecessary()。在这一步就找到目标类的所有通知方法
  protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
// 获取到目标类关联的所有通知方法
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
  • 通过代理工厂创建增强bean
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {

        return proxyFactory.getProxy(this.getProxyClassLoader());
    }
  • 通过JDK动态代理或者CGLIB动态代理

跟进去proxyFactory.getProxy(this.getProxyClassLoader());,再跟进去createAopProxy(),再跟进去createAopProxy()

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
// 如果实现了接口那么就使用jdk代理
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }
  • 给容器中返回增强后的代理对象
  • 执行目标方法的时候,代理对象会执行通知方法的流程

 

执行目标方法(切面拦截)的流程

  • CglibAopProxy.intercept();拦截目标方法的执行
  • 根据ProxyFactory对象获取将要执行的目标方法拦截器链;List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  • List<Object> interceptorList保存所有拦截器 5个 一个默认的ExposeInvocationInterceptor 和 4个增强器
  • 遍历所有的增强器,将其转为Interceptor; registry.getInterceptors(advisor);
  • 将增强器转为List<MethodInterceptor>;如果是MethodInterceptor,直接加入到集合中。如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;转换完成返回MethodInterceptor数组;
  • 如果没有拦截方法,那么直接执行目标方法
  • 如果有则采用拦截器的链式机制,依次进入每一个拦截器进行执行

每一个通知方法都有其专门的处理拦截类

​
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Object target = null;
            TargetSource targetSource = this.advised.getTargetSource();

            Object var16;
            try {
                if (this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = targetSource.getTarget();
                Class<?> targetClass = target != null ? target.getClass() : null;
// 根据ProxyFactory对象获取将要执行的目标方法拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);
                } else {
                    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
                }

                retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
                var16 = retVal;
            } finally {
                if (target != null && !targetSource.isStatic()) {
                    targetSource.releaseTarget(target);
                }

                if (setProxyContext) {
                    AopContext.setCurrentProxy(oldProxy);
                }

            }

            return var16;
        }

​

进入proceed();

    public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.invokeJoinpoint();
        } else {
// 获取第一个通知方法
            Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
            } else {
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }

调用invoke方法,再invoke方法中又会调用proceed()方法,遍历所有的增强器,这里只列举了三个,可以看到只有MethodBeforeAdviceInterceptor是先执行逻辑,再执行proceed,然后一层层执行其它的增强器。

    public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
        invocation.set(mi);

        Object var3;
        try {
            var3 = mi.proceed();
        } finally {
            invocation.set(oldInvocation);
        }

        return var3;
    }

 

    public Object invoke(MethodInvocation mi) throws Throwable {
        Object var2;
        try {
            var2 = mi.proceed();
        } finally {
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
        }

        return var2;
    }

 

    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值