什么是AOP?有什么好处?怎么实现的?

6 篇文章 0 订阅

什么是AOP?

AOP(Aspect-Oriented-Programing)面向切面编程,是一种编程理念。该理念能够是那些为多个业务所共有,却与业务逻辑没有关系的模块抽取出来,形成一个切面。这样可以减少重复代码,并使业务逻辑保持简单,是代码易于维护和扩展。
Spring中是怎么实现AOP的?
Spring是通过JDK动态代理和CGLib(Code Generation Library)字节码生成技术,来实现AOP的,默认在对象存在接口时,使用JDK动态代理,否则使用CGLib。

先看下静态代理

在这里插入图片描述

public class AopTest {
    public static void main(String[] args) {
        Student student=new Student("lily");
        student.speak();
    }
}
public interface IStudent {
    void speak();
}
public class Student implements IStudent{
    String name;

    public Student(String name) {
        this.name = name;
    }

    public void speak(){
        System.out.println("my name is "+name);
    }
}

执行main 方法得到

my name is lily

如果我们想在student对象speak之前都加一个句,“hello !”,怎么实现呢?
可以使用代理模式,即新写一个类继承Istudent,然后传入student。

public class StudentProxy implements Humen{
    Student student;
    public StudentProxy(Student student) {
    this.student=student;
    }

    @Override
    public void speak() {
        System.out.println("hello !");
        student.speak();
    }
}
public class AopTest {
    public static void main(String[] args) {
        Student student=new Student("lily");
        StudentProxy studentProxy=new StudentProxy(student);
        studentProxy.speak();
    }
}

执行得到:

hello !
my name is lily

静态代理成功。

如果有多个方法都要代理呢,那么我们就要在静态代理中写对应个数的代理方法。这很显然不够灵活。

那么就引出了动态代理。

public class DynamicProxy implements InvocationHandler {
    private Object object;

    public DynamicProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("hello !");
        Object result=method.invoke(object,args);
        return result;
    }
}

建立一个某功能的动态代理类,可以用来校验,或者记录日志,即我们常用的AOP功能。
继承自InvocationHandler,并将想要增强的功能写在invoke重写方法里。

使用

public class AopTest {
    public static void main(String[] args) {
        Student student=new Student("lily");
        //使用动态代理类代理对象
        DynamicProxy dynamicProxy=new DynamicProxy(student);
        //使用该代理类
        IStudent student1=(IStudent) Proxy.newProxyInstance(IStudent.class.getClassLoader(),new Class[]{IStudent.class},dynamicProxy);
        student1.speak();
    }
}

结果:

hello !
my name is lily

成功代理该对象。

添加一个ask 方法

public interface IStudent {
    void speak();
    void ask();
}
public class Student implements IStudent{
    String name;

    public Student(String name) {
        this.name = name;
    }

    public void speak(){
        System.out.println("my name is "+name);
    }
    public void ask(){
        System.out.println("who is "+name);
    }
}

调用:

public class AopTest {
    public static void main(String[] args) {
        Student student=new Student("lily");
        //使用动态代理类代理对象
        DynamicProxy dynamicProxy=new DynamicProxy(student);
        //使用该代理类
        IStudent student1=(IStudent) Proxy.newProxyInstance(IStudent.class.getClassLoader(),new Class[]{IStudent.class},dynamicProxy);
        student1.speak();
        student.ask();
    }
}

结果:

hello !
my name is lily
hello !
who is lily

ask方法也被代理了。

使用动态代理的流程为:

1.写动态代理类,继承自InvocationHandler 并重写invoke方法,在该方法中进行增强。
2.通过代理类传入希望被代理对象,生成动态代理对象
3.将动态代理对象传入Proxy静态方法newProxyInstance,得到已被代理的对象
4.通过已被代理对象执行方法

关于动态代理和CGLib应用的具体代码,见:这篇文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值