SpringAOP的原理及仿写

什么是AOP

AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。

为什么需要AOP

想象下面的场景,开发中在多个模块间有某段重复的代码,我们通常是怎么处理的?显然,没有人会靠“复制粘贴”吧。在传统的面向过程编程中,我们也会将这段代码,抽象成一个方法,然后在需要的地方分别调用这个方法,这样当这段代码需要修改时,我们只需要改变这个方法就可以了。然而需求总是变化的,有一天,新增了一个需求,需要再多出做修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。实际上涉及到多个地方具有相同的修改的问题我们都可以通过 AOP 来解决。

AOP的实现

AOP本质上其实是代理模式,定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理。

jdk动态代理实现
基本类

//定义的接口HelloService
public interface HelloService {
    void sayHello();
}
//接口的实现类
public class HelloServiceImpl implements HelloService {
    public void sayHello() {
        System.out.println("Hello");
    }
}

通知类

//Advice,继承了 InvocationHandler 接口
public interface Advice extends InvocationHandler {
	
}
//实现了 Advice 接口,是一个前置通知
public class BeforeAdvice implements Advice{
	//真实类的对象
    private Object bean;
    //通知内容
    private MethodInvocation methodInvocation;
    public BeforeAdvice(Object bean,MethodInvocation methodInvocation){
        this.bean=bean;
        this.methodInvocation=methodInvocation;
    }
   //当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	//前置通知内容
        methodInvocation.invoke();
        // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        method.invoke(bean, args);
        return null;
    }
}
//通知内容,实现类包含了切面逻辑
public interface MethodInvocation {
    void invoke();
}

AOP实现类

//生成代理类
public class SimpleAOP {
    public static Object getProxy(Object bean,Advice advice){
        return Proxy.newProxyInstance(SimpleAOP.class.getClassLoader(),bean.getClass().getInterfaces(), advice);
    }
}

测试类

public class TestAop {
    public static void main(String[] args) {
        // 1. 创建一个 MethodInvocation 实现类
        MethodInvocation logTask = () -> System.out.println("log task start");
        HelloServiceImpl helloServiceImpl = new HelloServiceImpl();

        // 2. 创建一个 Advice
        Advice beforeAdvice = new BeforeAdvice(helloServiceImpl,logTask);

        // 3. 为目标对象生成代理
        HelloService helloServiceImplProxy = (HelloService) SimpleAOP.getProxy(helloServiceImpl,beforeAdvice);

		//调用方法
        helloServiceImplProxy.sayHello();
    }
}

附加

Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 
proxy:  - 指代我们所代理的那个真实对象
method: - 指代的是我们所要调用真实对象的某个方法的Method对象
args:  - 指代的是调用真实对象某个方法时接受的参数
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
 
loader:      一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
 
interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
 
h:           一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值