spring(三)---aop底层实现原理

一、jdk实现原理

1、接口

package top.einino.service;

public interface BankService {

void getMoney( Double money);
}

2、接口实现类

package top.einino.service.impl;

import top.einino.service.BankService;

public class BankServiceImpl implements BankService {

public void getMoney(Double money) {
System.out.println(“取出:”+money+”元”);
}

}

3、代理机制

package top.einino.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxy implements InvocationHandler {

private Object target;//要代理的目标对象

public JDKProxy(Object target){
this.target = target;
}

public Object createProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),//类加载
target.getClass().getInterfaces(),//类接口
this);//实现invocationHandler接口
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(“写入日记”);
Object result = method.invoke(target, args);
return result;
}
}

4、测试

package top.einino.junit;

import top.einino.proxy.JDKProxy;
import top.einino.service.BankService;
import top.einino.service.impl.BankServiceImpl;

public class TestJdkProxy {

public static void main(String[] args) {
//代理的目标对象
BankServiceImpl bankServiceImpl = new BankServiceImpl();
//实现代理的类
JDKProxy jdkProxy = new JDKProxy(bankServiceImpl);
//创建代理对象
BankService bankServiceProxy = (BankService) jdkProxy.createProxy();
//执行操作
bankServiceProxy.getMoney(2000.0d);
}
}

缺点: 使用Jdk动态代理,必须要求target目标对象,实现接口 ,如果没有接口,不能使用Jdk动态代理

二、Cglib动态代理实现原理

1、无接口的类

package top.einino.service.impl;

public class BankServiceWithCglib {

public void getMoney(Double money) {
System.out.println(“取出:”+money+”元”);
}

}

2、创建代理类

package top.einino.proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{

private Object target;//要代理的目标对象

public CglibProxy(Object target){
this.target = target;
}

public Object createProxy(){
//创建enhancer对象
Enhancer enhancer = new Enhancer();
//创建代理,对目标对象,创建子类对象
enhancer.setSuperclass(target.getClass());
//传入callback对象,对目标增强
enhancer.setCallback(this);

return enhancer.create();
}
//第一个参数代理对象,第二个参数代理方法,第三个参数代理方法参数列表,第四个参数代理对象的代理方法
@Override
public Object intercept(Object proxy, Method method, Object[] arg2,
MethodProxy methodProxy) throws Throwable {

System.out.println(“写入日记”);
return methodProxy.invokeSuper(proxy, arg2);

}

}

3、测试

package top.einino.junit;

import top.einino.proxy.CglibProxy;
import top.einino.service.BankService;
import top.einino.service.impl.BankServiceWithCglib;

public class TestCglibProxy {

public static void main(String[] args) {

//代理的目标对象
BankServiceWithCglib bankServiceWithCglib = new BankServiceWithCglib();
//执行代理的代理类
CglibProxy cglibProxy = new CglibProxy(bankServiceWithCglib);
//创建代理对象
BankServiceWithCglib BankServiceWithCglibProxy = (BankServiceWithCglib) cglibProxy.createProxy();
//执行操作
BankServiceWithCglibProxy.getMoney(2000.0d);

}
}

三、两者对比

Cglib 创建代理思想: 对目标类创建子类对象

设置 superClass 对哪个类创建子类 (类似 JDK代理 接口)

设置 callback 实现增强代码 (类似 JDK代理 InvocationHandler )

在cglib的callback函数中,要执行被代理对象的方法

method.invoke(target, args); 等价于 methodProxy.invokeSuper(proxy, args);

优先对接口代理 (使用JDK代理),如果目标没有接口,才会使用cglib代理 !

四、小结

该博文主要介绍了spring的aop实现原理,以及这两个原理的对比和实际运用时是如何调用。

如果有疑问或者对该博文有何看法或建议或有问题的,欢迎评论,恳请指正!

    原文作者:AOP
    原文地址: https://blog.csdn.net/eininotop/article/details/70254936
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞