对AOP进行举例,Spring AOP的底层实现机制,真正在使用Spring AOP进行开发时,不需要这么复杂,可以用更好理解的方式来开发。
解耦合前
创建一个AOP文件夹
Cal接口
package com.linko.aop;
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);
}
CalImpl实现类
package com.linko.aop.impl;
import com.linko.aop.Cal;
public class CalImpl implements Cal {
public int add(int num1, int num2) {
int result = num1 + num2;
return result;
}
public int sub(int num1, int num2) {
int result = num1 + num2;
return result;
}
public int mul(int num1, int num2) {
int result = num1 * num2;
return result;
}
public int div(int num1, int num2) {
int result = num1 / num2;
return result;
}
}
CalImpl
package com.linko.aop.impl;
import com.linko.aop.Cal;
public class CalImpl implements Cal {
public int add(int num1, int num2) {
//以下表示耦合度很高,就是紧紧凑在一起
System.out.println("add方法的参数是["+num1 + "," + num2 + "]");//输入和输出是非业务代码
int result = num1 + num2;//这个是业务代码
System.out.println("add方法的结果是"+result);
return result;
}
public int sub(int num1, int num2) {
System.out.println("sub方法的参数是["+num1 + "," + num2 + "]");
int result = num1 + num2;
System.out.println("sub方法的结果是"+result);
return result;
}
public int mul(int num1, int num2) {
System.out.println("mul方法的参数是["+num1 + "," + num2 + "]");
int result = num1 * num2;
System.out.println("mul方法的结果是"+result);
return result;
}
public int div(int num1, int num2) {
System.out.println("div方法的参数是["+num1 + "," + num2 + "]");
int result = num1 / num2;
System.out.println("div方法的结果是"+result);
return result;
}
}
Test
package com.linko.aop;
import com.linko.aop.impl.CalImpl;
public class Test {
public static void main(String[] args) {
Cal cal = new CalImpl();
cal.add(10,3);
cal.sub(10,3);
cal.mul(10,3);
cal.div(10,3);
}
}
日志打印
- 在每个方法开始位置输出参数信息
- 在每个方法结束位置输出结果信息
对于计算器来讲,加减乘除就是业务代码,日志打印就是非业务代码。因为输入输出不是你所要关心的。
以上输入输出重复性很大,复制很多,修改、维护性很差。所以需要我们解耦合。
解耦合后
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H4qphlGc-1627888373829)(C:/Users/%E6%9E%97%E5%A5%8E/Pictures/Typora/image-20210727204045398.png)]
CalImpl
package com.linko.aop.impl;
import com.linko.aop.Cal;
public class CalImpl implements Cal {
public int add(int num1, int num2) {
// System.out.println("add方法的参数是["+num1 + "," + num2 + "]");
int result = num1 + num2;
// System.out.println("add方法的结果是"+result);
return result;
}
public int sub(int num1, int num2) {
// System.out.println("sub方法的参数是["+num1 + "," + num2 + "]");
int result = num1 + num2;
// System.out.println("sub方法的结果是"+result);
return result;
}
public int mul(int num1, int num2) {
// System.out.println("mul方法的参数是["+num1 + "," + num2 + "]");
int result = num1 * num2;
// System.out.println("mul方法的结果是"+result);
return result;
}
public int div(int num1, int num2) {
// System.out.println("div方法的参数是["+num1 + "," + num2 + "]");
int result = num1 / num2;
// System.out.println("div方法的结果是"+result);
return result;
}
}
MyInvocationHandler
package com.linko.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class MyInvocationHandler implements InvocationHandler {
//本身不是代理类,我们是通过这个类来生成代理类
//委托对象
private Object object = null;
//返回代理对象
public Object bind(Object object){
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(),
this);//获取代理的一个实例化对象
}
//proxy就是Test里的那个对象,method指的是add等函数,args数组指的是传的参数
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;
}
}
Test
package com.linko.aop;
import com.linko.aop.impl.CalImpl;
import com.linko.ioc.MyClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//实例化委托对象
Cal cal = new CalImpl();
//获取代理对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
Cal proxy = (Cal)myInvocationHandler.bind(cal);
proxy.add(10,3);
proxy.sub(10,3);
proxy.mul(10,3);
proxy.div(10,3);
}
}