昨天在实现动态代理的时侯:https://blog.csdn.net/qq_42394457/article/details/88550481
以为只能用接口实现,但是我今天学习 aop 的时候,发现 aop 里 , 一个 类 , 不需要实现 接口
也能被 ioc 创建 动态代理
我后来google了,发现 , 我昨天实现的是 jdk 的动态代理,而 jdk 的动态代理对象必须通过接口获取
因为 代理对象和被代理对象之间 唯一 有联系的 就是 接口 , 而 无需 实现接口就能创建 代理对象的动态代理 是 cglib 实现的 ,如果需要详细了解其中区别的同学,可以参考这位 大神写的一篇博文:
https://blog.csdn.net/yhl_jxy/article/details/80635012
然后贴上 spring aop 关于 2 种 方式的实现:
首先是 jdk 的:
接口:
/**
* 接口可以加在容器中,但是 ioc 容器 不会 加载它,而且 ioc 也无法 创建这个接口的对象
*/
public interface Calculate {
public abstract int add(int a, int b);
public abstract int sub(int a, int b);
public abstract int mul(int a, int b);
public abstract int div(int a, int b);
}
接口实现类:
import org.springframework.stereotype.Service;
/**
* 容器中保存的是这个类的代理对象 , 而这个类的实例 和 代理对象之间的关联就是他们
* 是实现同一个 接口 Calculate
*/
@Service
public class MyCalculate /*implements Calculate*/{
//加法
public int add(int a , int b){
return a + b;
}
//减法
public int sub(int a , int b){
return a - b;
}
//加法
public int mul(int a , int b){
return a * b;
}
//加法
public int div(int a , int b){
return a / b;
}
}
切面类:
@Aspect
@Component
public class LogUtil {
/*
* execution 是 切面表达式
* @Before: 表示 在目标方法开始时执行
* @After: 表示 在 目标方法结束后执行
* @AfterReturning: 表示在 目标方法返回后 执行
* @AfterThrowing: 表示在 目标 方发抛出异常后 执行
*/
/**
* 在目标方法开始运行时执行
*/
@Before("execution(public int com.yg.aop.proxy.MyCalculate.*(int,int))")
public static void logStart(){
System.out.println("方法开始运行");
}
/**
* 在目标方法抛出异常时执行
*/
@AfterThrowing("execution(public int com.yg.aop.proxy.MyCalculate.*(int,int))")
public static void logThrowing(){
System.out.println("方法运行时");
}
/**
* 在目标方法返回时执行
*/
@AfterReturning("execution(public int com.yg.aop.proxy.MyCalculate.*(int,int))")
public static void logReturning(){
System.out.println("方法返回");
}
/**
* 在目标方法结束后执行
*/
@After("execution(public int com.yg.aop.proxy.MyCalculate.*(int,int))")
public static void logAfter(){
System.out.println("方法结束");
}
}
测试:
public class Test {
public static void main(String[] args) {+
/**
* 测试 aop 面向切面 编程的 方法
*/
ApplicationContext context = new ClassPathXmlApplicationContext("firstAop.xml");
/**
* 使用 jdk 动态代理方式获取对象
*/
Calculate calculate = context.getBean(Calculate.class);
calculate.add(1,2);
System.out.println(calculate.getClass());
cglib的就是使 MyCalculate 不实现 Calculate 接口, 并且获取 对象的时候 , 使用 MyCalculate方式获取