美文网首页
spring aop

spring aop

作者: 江北晓白 | 来源:发表于2019-05-04 17:41 被阅读0次

aop面向切面编程,核心的东西是动态代理模式:cglib和jdk
先说aop的用法,百度搜索能够搜到很多相关用法的总结,下面简单的归类下aop的知识点:
基本概念:aspect(切面,属于某个模块的总称@aspect @configuration)、pointcut(表明要切入的切口点,具体用法见下文)、jointcut(连接点的概念,包括切入点传入的参数,属性,及返回值等)、advice(@around、@before、@after、@afterRetruning、@afterThrowing,这几个注解的用法不是很复杂,主要理清一下先后顺序就可以,顺序见下文)、weaving(织入的概念,其实就是加载进字节码,程序运行的时候能够找到,分为两种,分别是编译时增强(AspectJ)、运行时增强(CGLIB,spring aop为此种类型))、target object(被织者,很简单的概念,没有多余的东西)、aop proxy object(织入的过程,反向代理(本文主要要讲的理论,动态代理的代码很嗨,见下文))。

@pointcut

pointcut切点的表达式,语法有多种形式,其中包括:
1、excution([可见性(public/private/default)]+返回类型+[声明类型].方法名(参数)[异常] )其中[]可以不填,同时在切片表达式中可以添加&&、||、!进行拼接,也可以通过省略多个字符,..省略多个参数,+拼接多个类及其子类
@Pointcut("execution(
com.cjm.model...(..))")
public void pointcut(){}
2、within:
3、this:
4、target:
5、args:
6、@within@target@args
7、annotation
8、bean:示例如下,其中指定了bean对象的名字被限定为person
上述除了execution起到执行功能外,其他的声明类型都是起到限制的作用,具体用法见链接https://www.cnblogs.com/zhaww/p/8674657.html
@Pointcut("bean(person)")
public void pointcut(){}

@advice

主要有五种增强注解,按照织入顺序排序为:

around->before->around->after->afterReturning->afterThrowing

Jointcut

Jointcut中常用方法包括getArgs、getThis(返回代理对象)、getTarget、getSignature(返回被增强方法的相关信息),ProceedingJoinPoint继承自Jointcut,主要增加了proceed(可传入参数object[],用于传入目标方法的参数)方法,用于around增强时运行目标方法。

@around(pointcut="")
public around(ProceedingJoinPoint jp)
{
//before前
 jp.proceed();//执行增强方法
//after前
}

aop proxy object

动态代理有两种类型,分别是CGLIB、JDK。其中JDK动态代理,是基于接口实现的,而CGLIB是基于继承类实现的。
jdk动态代理的简单举例,后续会研究一下反射的具体实现:

public class jdkTest {
    public  static  void main(String[] args){
        proxytest1 proxytest1 = new test1();
        proxytest proxytest = new proxytest(proxytest1);
        proxytest1 test= (proxytest1) Proxy.newProxyInstance(proxytest1.getClass().getClassLoader(),proxytest1.getClass().getInterfaces(),proxytest);
        test.send();
    }
}
 其中proxytest1是接口:

public interface proxytest1 {
    public void send();
}
test1时实现proxytest1接口的类:
public class test1 implements  proxytest1 {
    @Override
    public void send(){
        System.out.println("加油大兄弟,run");
    }
}
代理类的实现如下:
public class proxytest implements InvocationHandler {

    private Object test;

    proxytest(Object test){
        this.test = test;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        Object invoke = method.invoke(test,args);
        return invoke;
    }
}
通过该代理类,重写了invoke方法,并通过Proxy.newProxyInstance方法传入ClassLoader、interfaces和invocationHandler,并返回对应的接口对象中,当接口对象调用方法时,会调用invoke函数,动态加载该方法。

CGLIB动态代理主要是通过类继承来实现的:

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Landlord.class);
enhancer.setCallback(intermediary);//intermediary继承自MethodInterceptor并重写了intercept方法        
Landlord rentProxy = (Landlord) enhancer.create();
rentProxy.rent();

https://www.cnblogs.com/lxcmyf/p/6433018.html动态代理举例。

相关文章

网友评论

      本文标题:spring aop

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