AOP小案例
AOP (Aspect Oriented Programming)面向切面编程。
00P (Object Oriented Programming)面向对象编程,用对象化的思想来完成程序。
AOP是对0OP的一个补充,是在另外一个维度上抽象出对象。
具体是指程序运行时动态地将非业务代码切入到业务代码中,从而实现程序的解耦合,将非业务代码抽象成一个对
象,对该对象编程就是面向切面编程。
![在这里插入图片描述](https://img-blog.csdnimg.cn/3542d9c492b44dd5ad9e04978cb46a0e.png)
上述形式代码维护性差,没有代码复用性。使用AOP进行优化,结果如下图所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6476026d4c884c00bc5fa349c86e959b.png)
AOP的优点
- 可以降低模块之间的耦合性
- 提高代码的复用性
- 提高代码的维护性
- 集中管理非业务代码,便于维护
- 业务代码不受非业务代码的影响,逻辑更加清晰
通过一个例子来理解AOP
1、创建一个计算器接口Cal
public interface Cal {
public int add(int num1, int num2);
public int sub(int num1, int num2);
public int mul(int num1, int num2);
public int div(int num1, int num2);
}
2、Cal接口实现类
public class Calimpl implements Cal {
int result;
@Override
public int add(int num1, int num2) {
result = num1 + num2;
return result;
}
@Override
public int sub(int num1, int num2) {
result = num1 - num2;
return result;
}
@Override
public int mul(int num1, int num2) {
result = num1 * num2;
return result;
}
@Override
public int div(int num1, int num2) {
result = num1 / num2;
return result;
}
}
日志打印
- 在每个方法开始位置输出参数信息。
- 在每个方法结束位置输出结果信息。
对于计算器来讲,加减乘除就是业务代码,日志打印就是非业务代码。
public class Calimpl implements Cal {
int result;
@Override
public int add(int num1, int num2) {
System.out.println("add方法的参数是" + num1 + "," + num2);
result = num1 + num2;
System.out.println("add方法的结果是:" + result);
return result;
}
@Override
public int sub(int num1, int num2) {
System.out.println("sub方法的参数是" + num1 + "," + num2);
result = num1 - num2;
System.out.println("sub方法的结果是:" + result);
return result;
}
@Override
public int mul(int num1, int num2) {
System.out.println("mul方法的参数是" + num1 + "," + num2);
result = num1 * num2;
System.out.println("mul方法的结果是:" + result);
return result;
}
@Override
public int div(int num1, int num2) {
System.out.println("div方法的参数是" + num1 + "," + num2);
result = num1 / num2;
System.out.println("div方法的结果是:" + result);
return result;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/aaee56d1317d4454ac3bc5c2055b5417.png)
AOP如何实现?使用动态代理的方式来实现。
代理首先应该具备Calimpl的所有功能,并在此基础上,扩展出打印日志的功能。
1、删除Calimpl方法中所有打印日志的代码,只保留业务代码。
![在这里插入图片描述](https://img-blog.csdnimg.cn/051744dda6f74d2eb25eb8c91716e265.png)
2、创建MyInvocationHandler类,实现InvocationHandler接口,生成动态代理类。动态代理类,需要动态生成,需要获取到委托类的接口信息,根据这些接口信息动态生成一个代理类,然后再由ClassLoader用来将动态生成的类加载到JVM 中。
public class MyInvocationHandler implements InvocationHandler {
private Object object = null;
public Object getbind(Object object) {
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"方法的参数是" + Arrays.toString(args));
Object result = method. invoke(this.object,args);
System.out.println(method.getName()+"方法的结果是:" + result);
return result;
}
}
public class Test_Cal {
public static void main(String[] args) {
Cal cal = new Calimpl();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
Cal proxy = (Cal) myInvocationHandler.getbind(cal);
proxy.add(7, 2);
proxy.sub(7, 2);
proxy.mul(7, 2);
proxy.div(7, 2);
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/647b2a8676fc44caa78e3d1bc347f372.png)
上述代码通过动态代理机制实现了业务代码和非业务代码的解耦合,这是Spring AOP的底层实现机制,真正在使用Spring AOP进行开发时,不需要这么复杂,可以用更好理解的方式来完成开发。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)