SpringAOP

作者: wifiLIu | 来源:发表于2019-10-24 19:35 被阅读0次

    springAOP实现方式

    1.动态代理 使用 Proxy机制,使用反射技术,创建实际对象的代理对象,添加AOP的逻辑后执行。
    2.动态字节码增强 ASM CGLIB的工具库实现

    AOP概念

    1.joinpoint 目标对象上的要执行AOP的具体执行点。和pointcut类似于对象实例和类的概念,pointcut规定一组判断逻辑,符合多级的具体点就是一个个的joinpoint,而pointcut规定的表达式指定的则是一组joinpoint。
    2.pointcut 需要执行AOP切入的一个切入点,这个点是所有符合该cut定义的位置的集合(expression="execution()")
    3.advice AOP的增强逻辑代码,针对一个point指定的方法定义的要做的逻辑操作。advice可以是方法前、后、异常、环绕等概念
    advice根据不同的执行顺序定义为before,afterreturning,afterthrowing,after,around,以及interceptor等不同的advise。
    4.aspect 关联advice和pointcut的概念实体,通过aspect的定义,可以组合advice到pointcut中。
    5.weaver 织入器,把aop的advice插入到目标对象的横切点中去的具体实现。


    AOP概念 pointcut的局部分支图 image.png
    image.png
    image.png image.png

    动态代理

    spring 动态代理机制使用 ProxyInvocationHandler两个reflect包中的对象来实现运行时的动态代理机制。

    package com.lwf.jms;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class test {
        public static void main(String[] args) {
            Itest test=(Itest) Proxy.newProxyInstance(test.class.getClassLoader(), new Class[]{Itest.class}, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("invocationHandler is ok");
    //                method.invoke(proxy,args);
                    System.out.println(proxy.getClass());
                   
                    System.out.println("method is over");
                    return null;
                }
            });
            test.talk();
            System.out.println(test.getClass());
        }
        interface Itest{
            void talk();
        }
    }
    
    

    spring集成并实现了cglib的字节码增强技术,主要通过enhancer 和callback的方法实现,一般情况下,callback都使用其子接口MethodInterceptor

    enhancer增强的类不能是内部类,内部类会默认读取到其外部类,从而出现错误。

    package com.lwf.jms;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class enhancertest {
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Talker.class);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("enhancer is starting");
                    System.out.println("method name :" + method.getName());
                    methodProxy.invokeSuper(o, objects);
                    System.out.println("enhancer is over");
                    return null;
                }
            });
            Talker talker = (Talker) enhancer.create();
            talker.talk();
            talker.speak();
        }
    
    }
    
    public class Talker {
        public void talk() {
            System.out.println("talker is talking");
        }
        public void speak() {
            System.out.println("talker is speaking");
        }
    }
    
    

    springAOP的代理实现

    springAOP中通过spring的动态代理机制实现AOP的植入,基础类为org.springframework.aop.framework.ProxyFactory,proxyfactory通过通过继承和扩展实现advicedSupport,通过组合内部拥有了一个AopProxyFactory的field(a opproxyfactory可以createproxy从而创建出proxy),集AopProxy和AdvicedSupport功能于一身,通过设置advisor来拥有AOP的定义,通过proxy功能来把aop功能植入到proxy代理对象中,实现功能!


    image.png
    image.png
    package com.lwf.jms;
    import org.springframework.aop.framework.ProxyFactory;
    import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
    public class ProxyFactoryTest {
        public static void main(String[] args) {
            ProxyFactory proxyFactory = new ProxyFactory(new Talker());
          //  proxyFactory.setOptimize(true);
          // proxyFactory.setProxyTargetClass(true);
            NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
            nameMatchMethodPointcutAdvisor.setMappedName("talk");
            nameMatchMethodPointcutAdvisor.setAdvice(new methodInterceptor());
            proxyFactory.addAdvisor(nameMatchMethodPointcutAdvisor);
            Talker proxy = (Talker) proxyFactory.getProxy();
           // proxy.speak();
            proxy.talk();
            System.out.println(proxy.getClass());
        }
    }
    package com.lwf.jms;
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    public class methodInterceptor implements MethodInterceptor {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("method name :"+invocation.getMethod().getName());
            Object rtn =invocation.proceed();
            System.out.println("invoke is over");
            return rtn;
        }
    }
    
    
    CGLIB执行结果
    proxy执行结果

    methoeinterceptor类使用的是org.aopalliance.intercept.MethodInterceptor,在CGLIB中


    image.png

    springAOP的自动代理机制

    proxyfactorybean实现了spring的aop植入,那么spring如何实现自动化织入?spring借助applicationcontext的Ioc容器,通过BeanPostProcessor的Ioc初始化拦截进行操作。通过ioc容器的bean的初始化时添加一个给aop功能使用的BeanPostProcessor,在遍历初始化bean时实现autoproxy,生成代理对象。

    • 具体实现类
      spring在org.springframework.aop.framework.autoproxy包中提供了AutoProxyCreator类来实现自动代理功能
      autoproxycreator的结构图

    注解形式的AOP

    基于注解形式的aop是spring集成了aspectj中的注解,并利用aspectj中的注解相关的pointcut表达式进行pointcut解析,利用自动代理功能实现注解模式下的aop功能

     <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.9.4</version>
          <scope>compile</scope>
        </dependency>
    

    @aspect,@pointcut注解

    • pointcut表达式
      • execution()
      • within(@aspect class)
      • this 、target
        @before @after @around 实现advice逻辑功能

    相关文章

      网友评论

          本文标题:SpringAOP

          本文链接:https://www.haomeiwen.com/subject/ntlcvctx.html