SpringAOP

2019-10-24  本文已影响0人  wifiLIu

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,生成代理对象。

注解形式的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注解

上一篇下一篇

猜你喜欢

热点阅读