zoukankan      html  css  js  c++  java
  • spring AOP解析之注解方式详解

    切面类

    xml文件配置

    <aop:aspectj-autoproxy/>

    命名空间处理器是AopNamespaceHandler,我们可以看到这里注册了几个解析器,第一个我们知道是xml形式的解析,接下来我们看AspectJAutoProxyBeanDefinitionParser解析器

    <aop:aspectj-autoproxy/>标签注册了AnnotationAwareAspectJAutoProxyCreator对象

      @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
         // 注册AnnotationAwareAspectJAutoProxyCreator代理生成器 AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext);
    return null; }

     AnnotationAwareAspectJAutoProxyCreator对象

    我们可以看到他实现了BeanPostProcessor,BeanFactoryAware接口

    实现BeanFactoryAware接口的作用( AnnotationAwareAspectJAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator)

    @Override
        public void setBeanFactory(BeanFactory beanFactory) {
            super.setBeanFactory(beanFactory);
            if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
                throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
            }
            initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
        }
    @Override
        protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            super.initBeanFactory(beanFactory);
         // 创建BeanFactoryAspectJAdvisorsBuilder对象将ReflectiveAspectJAdvisorFactory对象注入进去
    this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); }

    实现BeanPostProcessor接口的作用

      @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (!this.earlyProxyReferences.contains(cacheKey)) {
              // 初始化bean如goodService后,创建其代理对象
    return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // 根据注解信息获得通知和广播,后文详解
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 创建代理对象 Object proxy
    = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
         // 根据注解信息获得广播 List
    <Advisor> candidateAdvisors = findCandidateAdvisors();
         // 根据表达式匹配符合的广播 List
    <Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

    AnnotationAwareAspectJAutoProxyCreator中获得所有的注解广播

    @Override
        protected List<Advisor> findCandidateAdvisors() {
            // 获得所有的xml形式配置的广播
            List<Advisor> advisors = super.findCandidateAdvisors();
            // 获得所有注解形式配置的广播
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
            return advisors;
        }

     根据注解信息创建广播

    public List<Advisor> buildAspectJAdvisors() {
            List<String> aspectNames = null;
    
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new LinkedList<Advisor>();
                    aspectNames = new LinkedList<String>();
              // 获得所有已经注册了的bean String[] beanNames
    = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); for (String beanName : beanNames) {
                // 判断bean是否符合条件,根据<aop:include name=""/>标签信息判断
    if (!isEligibleBean(beanName)) { continue; } // 获得切面类的Class Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; }
                // 判断bean是否被注解@Aspect注释了
    if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName);
                   // 使用org.aspectj的API AjType来填充AspectMetadata对象,后文详解#1   AspectMetadata amd
    = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     // 创建对象其中有BeanFactory,beanName,AspectMetadata MetadataAwareAspectInstanceFactory factory
    = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     // 获得所有的广播,后文详解#2 List
    <Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     // 将广播放到缓存中
    if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new LinkedList<Advisor>();
         // 再过来拿Advisors广播时,从缓存中拿
    for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }

     书接前文#1

    构建AspectMetadata对象时

    public AspectMetadata(Class<?> aspectClass, String aspectName) {
            this.aspectName = aspectName;
    
            Class<?> currClass = aspectClass;
            AjType<?> ajType = null;
            while (currClass != Object.class) {
                AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);
                if (ajTypeToCheck.isAspect()) {
                    ajType = ajTypeToCheck;
                    break;
                }
                currClass = currClass.getSuperclass();
            }
            if (ajType == null) {
                throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
            }
            if (ajType.getDeclarePrecedence().length > 0) {
                throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
            }
            this.aspectClass = ajType.getJavaClass();
            this.ajType = ajType;
    
            switch (this.ajType.getPerClause().getKind()) {
                case SINGLETON :
                    this.perClausePointcut = Pointcut.TRUE;
                    return;
                case PERTARGET : case PERTHIS :
                    AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
                    ajexp.setLocation("@Aspect annotation on " + aspectClass.getName());
                    ajexp.setExpression(findPerClause(aspectClass));
                    this.perClausePointcut = ajexp;
                    return;
                case PERTYPEWITHIN :
                    // Works with a type pattern
                    this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
                    return;
                default :
                    throw new AopConfigException(
                            "PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
            }
        }

    书接前文#2

    @Override
        public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
            Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
            String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
            validate(aspectClass);
         // 创建MetadataAwareAspectInstanceFactory对象为构造AspectJMethodBeforeAdvice对象作准备
            MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
                    new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
    
            List<Advisor> advisors = new LinkedList<Advisor>();
         // 获得除被@PointCut注解注释了的所有方法
    for (Method method : getAdvisorMethods(aspectClass)) {
            // 获得广播,后文详解#2-1 Advisor advisor
    = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }

    书接前文#2-1

    @Override
        public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                int declarationOrderInAspect, String aspectName) {
    
            validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
         // 获得AspectJExpressionPointcut对象为构造AspectJMethodBeforeAdvice等对象做准备
            AspectJExpressionPointcut expressionPointcut = getPointcut(
                    candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
            if (expressionPointcut == null) {
                return null;
            }
         // 创建InstantiationModelAwarePointcutAdvisorImpl对象其中包含AspectJMethodBeforeAdvice等通知对象
            return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                    this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
        }
    public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
                Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
                MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    
            this.declaredPointcut = declaredPointcut;
            this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
            this.methodName = aspectJAdviceMethod.getName();
            this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
            this.aspectJAdviceMethod = aspectJAdviceMethod;
            this.aspectJAdvisorFactory = aspectJAdvisorFactory;
            this.aspectInstanceFactory = aspectInstanceFactory;
            this.declarationOrder = declarationOrder;
            this.aspectName = aspectName;
    
            if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
                // Static part of the pointcut is a lazy type.
                Pointcut preInstantiationPointcut = Pointcuts.union(
                        aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
    
                // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
                // If it's not a dynamic pointcut, it may be optimized out
                // by the Spring AOP infrastructure after the first evaluation.
                this.pointcut = new PerTargetInstantiationModelPointcut(
                        this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
                this.lazy = true;
            }
            else {
                // A singleton aspect.
                this.pointcut = this.declaredPointcut;
                this.lazy = false;
            // 工厂模式创建AspectJMethodBeforeAdvice等
    this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } }
    switch (aspectJAnnotation.getAnnotationType()) {
                case AtBefore:
                    springAdvice = new AspectJMethodBeforeAdvice(
                            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                    break;
    }

     接下来我们来看看创建代理对象成功之后,拦截过滤器和方法都做了什么?

    首先是使用cglib的api,Enhancer创建代理对象时,设置了CallbackFilter(ProxyCallbackFilter)的回调过滤器

    // 方法是获得MethodBeforeAdviceInterceptor等通知拦截,然后缓存起来
    List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
            MethodCacheKey cacheKey = new MethodCacheKey(method);
            List<Object> cached = this.methodCache.get(cacheKey);
            if (cached == null) {
                cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                        this, method, targetClass);
                this.methodCache.put(cacheKey, cached);
            }
            return cached;
        }
    @Override
        public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
                Advised config, Method method, Class<?> targetClass) {
    
            List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
            Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
            boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
            AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
         // 遍历所有的广播如InstantiationModelAwarePointcutAdvisorImpl
            for (Advisor advisor : config.getAdvisors()) {
                if (advisor instanceof PointcutAdvisor) {
                    PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                    if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                // 获得方法拦截器,后文详解#3
                        MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                        MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                        if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                            if (mm.isRuntime()) {
                                for (MethodInterceptor interceptor : interceptors) {
                                    interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                                }
                            }
                            else {
                                interceptorList.addAll(Arrays.asList(interceptors));
                            }
                        }
                    }
                }
                else if (advisor instanceof IntroductionAdvisor) {
                    IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                    if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                        Interceptor[] interceptors = registry.getInterceptors(advisor);
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
                else {
                    Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
    
            return interceptorList;
        }

    书接前文#3

    @Override
        public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
            List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
            Advice advice = advisor.getAdvice();
            if (advice instanceof MethodInterceptor) {
                interceptors.add((MethodInterceptor) advice);
            }
         // 这里是将AfterReturningAdvice等通知转换成AfterReturningAdviceInterceptor方法拦截器
    for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if (interceptors.isEmpty()) { throw new UnknownAdviceTypeException(advisor.getAdvice()); } return interceptors.toArray(new MethodInterceptor[interceptors.size()]); }
      @Override
        public MethodInterceptor getInterceptor(Advisor advisor) {
         // 这里是从InstantiationModelAwarePointcutAdvisorImpl中拿到instantiatedAdvice属性值 AfterReturningAdvice advice
    = (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); }

    然后是Callback(DynamicAdvisedInterceptor)通知拦截回调

    // 从缓存中拿到AfterReturningAdviceInterceptor等方法拦截器
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    // 执行通知方法拦截回调链
    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
  • 相关阅读:
    Linux Screen
    python SQLAlchemy 学习
    python Django 分页功能
    大数据 HBase Shell
    HBase 表操作
    Nginx 编译安装
    python Django 发送邮件
    python Django 用户管理和权限认证
    python shutil 文件操作
    python zip 压缩文件
  • 原文地址:https://www.cnblogs.com/BINGJJFLY/p/7504564.html
Copyright © 2011-2022 走看看