spring aop和AspectJ的区别

2019-10-04  本文已影响0人  7d972d5e05e8

原文:https://www.zhoujunwen.com/2018/aop-aspectj-springaop

AOP的代理类的创建在,doCreateBean方法中的initializeBean()。该方法主要是调用所有实现了BeanPostProcessor类的后处理器。

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中,

@Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

BeanPostProcessor中的一个实现类,AnnotationaWAREaspectJAutoProxyCreatore类,执行了postProcessAfterInitialization方法,实现了动态代理。

二、什么是AspectJ?

引用文章:https://segmentfault.com/a/1190000015262333

在网上一搜一大片所谓AspectJ的用法,其实都是AspectJ的“切面语法”,只是AspectJ框架的冰山一角,AspectJ是完全独立于Spring存在的一个Eclipse发起的项目,官方关于AspectJ的描述是:

Eclipse AspectJ is a seamless aspect-oriented extension to the Java™ programming language. It is Java platform compatible easy to learn and use.
是的AspectJ甚至可以说是一门独立的语言,我们常看到的在spring中用的@Aspect注解只不过是Spring2.0以后使用了AspectJ的风格而已本质上还是Spring的原生实现,关于这点Spring的手册中有提及:

@AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。@AspectJ样式在AspectJ 5发布的AspectJ project部分中被引入。Spring 2.0使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器(weaver)。

so 我们常用的org.aspectj.lang.annotation包下的AspectJ相关注解只是使用了AspectJ的样式,至于全套的AspectJ以及织入器,那完全是另一套独立的东西。

总结:
  1. 原生的aspectJ,其实是静态代理。它有自己的一套编译器,通过命令:

ajc -d . Hello.java TxAspect.aj

实现了在编译阶段生成代理类

  1. spring中的@AspectJ,本质上使用的还是动态代理。它的实现类AspectJAwareAdvisorAutoProxyCreator继承了AbstractAutoProxyCreator。该类是spring的aop包,和aspectJ一点都不沾边。@AspectJ注解,实现代理的源码如下:
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;

createProxy方法实现,还是使用了JDK或者cglib来实现的动态代理。

以后再说两者的区别,一定要区分是AspectJ原生,还是@AspectJ注解。

引用网上的一句话:

Spring AOP
spring aop常被人诟病复杂,难用。但又有多少新司机真正的用过而不是上来就被@Aspectj那一套洗脑了,问你为什么spring aop难用,AspectJ的优势在哪又有多少人能答上来。
其实@AspectJ就是换了一个壳的Spring AOP而已

相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,
而Spring AOP则无需特定的编译器处理。

二、原生AspectJ的原理

(1)原理
AspectJ 意思就是Java的Aspect,Java的AOP。它的核心是ajc(编译器 aspectjtools)和 weaver(织入器 aspectjweaver)。

ajc编译器:基于Java编译器之上的,它是用来编译.aj文件,aspectj在Java编译器的基础上增加了一些它自己的关键字和方法。因此,ajc也可以编译Java代码。

weaver织入器:为了在java编译器上使用AspectJ而不依赖于Ajc编译器,aspectJ 5出现了 @AspectJ,使用注释的方式编写AspectJ代码,可以在任何Java编译器上使用。
由于AndroidStudio默认是没有ajc编译器的,所以在Android中使用@AspectJ来编写。它在代码的编译期间扫描目标程序,根据切点(PointCut)匹配,将开发者编写的Aspect程序编织(Weave)到目标程序的.class文件中,对目标程序作了重构(重构单位是JoinPoint),目的就是建立目标程序与Aspect程序的连接(获得执行的对象、方法、参数等上下文信息),从而达到AOP的目的。这个本质上,还是使用的spring aop的动态代理。

上一篇下一篇

猜你喜欢

热点阅读