AOP自定义标签

1.1 AOP的使用

1. 创建拦截的Bean
public class TestCase{

public void test() {
    System.out.println("TestCase 执行。。。");
}

}

2. 创建Advisor

@Component
@Aspect
public class JAspectTest {
    @Pointcut("execution(* *.insert (..))")
    public void testPointcut(){}

    @Before("testPointcut()")
    public ResponseRel beanAdvice(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("开始拦截。。。");
    }
}

3. 创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <aop:aspectj-autoproxy/>
</beans>

1.2 AOP处理流程

1.2.1 概述

  1. 默认标签解析注入AnnotationAwareAspectJAutoProxyCreator类
  2. AnnotationAwareAspectJAutoProxyCreator类处理流程
  3. 获得所有的增强器(getAdvicesAndAdvisorsForBean方法)
  4. 选择该类中用到的增强器(getAdvicesAndAdvisorsForBean方法)
  5. 创建代理(createProxy方法)

注:文章下文按照该概述流程列举源码

处理流程时序图:

这里写图片描述

1.2.2 默认标签解析注入

主要包括AopNamespaceHandler类和AspectJAutoProxyBeanDefinitionParser类

AopNamespaceHandler 源码:

    @Override
    public void init() {
        // In 2.0 XSD as well as in 2.1 XSD.
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

        // Only in 2.0 XSD: moved to context namespace as of 2.1
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }

解析器AspectJAutoProxyBeanDefinitionParser实现了BeanDefinitionParser,可知入口为parse方法
AspectJAutoProxyBeanDefinitionParser.parse() 源码:

    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
    // 注册AnnotationAwareAspectJAutoProxyCreator
    AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
    // 对于注解找那个子类的处理
        extendBeanDefinition(element, parserContext);
        return null;
    }

AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()源码:

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            ParserContext parserContext, Element sourceElement) {
// 注册或升级AutoProxyCreator定义beanName为AnnotationAwareAspectJAutoProxyCreator
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 对于proxy-target-class以及expose-proxy属性的处理
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // 注册组件并通知,便于监听器做进一步处理
        registerComponentIfNecessary(beanDefinition, parserContext);
    }

主要做了以下几个步骤:
1. 通过配置文件找到默认命名空间(AopNamespaceHandler 类)
2. 通过(AopNamespaceHandler 类)init方法注册BeanDefinitionParse解析(AspectJAutoProxyBeanDefinitionParser类)
3. 在(AspectJAutoProxyBeanDefinitionParser类)parse方法
4. 在(AopNamespaceUtils类中)注册或升级AutoProxyCreator定义beanName为 AnnotationAwareAspectJAutoProxyCreator;
对于proxy-target-class以及expose-proxy属性的处理;注册组件并通知,便于监 听器做进一步处理;

1.2.2 AnnotationAwareAspectJAutoProxyCreator类处理流程

AnnotationAwareAspectJAutoProxyCreator类的层次结果图如下所示:
AnnotationAwareAspectJAutoProxyCreator类的层次结果图
可以看出实现了InstantiationAwareBeanPostProcessor,在Bean实例化时会调用postProcessAfterInitialization方法

AbstractAutoProxyCreator类

@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
                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;
    }

主要做了以下几个步骤:
1. 实例化Bean之前调用postProcessAfterInitialization方法
2. 是否需要代理Bean,需要调用wrapIfNecessary方法
3. 获得代理Bean,调用getAdvicesAndAdvisorsForBean方法
4. 创建代理Bean,调用createProxy方法

1.2.3 获得所有的增强器

Spring获得增强器是在父类AnnotationAwareAspectJAutoProxyCreator实现

@Override
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }
    public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;

        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    // 获取所有beanName
                    List<Advisor> advisors = new LinkedList<Advisor>();
                    aspectNames = new LinkedList<String>();
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    // 循环所有的beanName找出对应的增强方法
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // We must be careful not to instantiate beans eagerly as in this case they
                        // would be cached by the Spring container but would not have been weaved.
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        // 如果存在Aspect注解
                        if (this.advisorFactory.isAspect(beanType)) {
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                // 解析标记AspectJ注解中的增强方法
                                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 {
                                // Per target or per this.
                                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>();
        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. 获得所有beanName,这一步骤会把BeanFactory中注册的所有bean提取处理
2. 遍历所有beanName,并找出声明AspectJ注解类
3. 对标记为AspectJ注解的类进行增强器的提取
4. 将提取出来的结果加入缓存

1.2.4 选择该类中用到的增强器

protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
        // 过滤已经得到的增强器
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
        // 首先处理引介增强器
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
        // 引接增强器已处理
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            // 不同bean处理
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }

1.2.5 创建代理

在AbstractAutoProxyCreator类中

protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(getProxyClassLoader());
    }

委托给ProxyFactory类

public Object getProxy() {
        // createAopProxy返回AopProxy,CglibAopProxy和JdkDynamicAopProxy实现了AopProxy
        return createAopProxy().getProxy();
    }

猜你喜欢

转载自blog.csdn.net/u010811939/article/details/80360116