Spring AOP引入之Java动态代理打印日志

概述

使用动态代理使得在不影响打印日志的类的情况下进行日志打印,也就解耦业务逻辑和日志打印

代码

代码执行流程:Proxy->获取代理ProxyCalculator.getProxy,代理执行对应的方法,并打印日志

测试类ProxyTest

1
2
3
4
5
6
7
8
9
10
11
12
import xyz.lyhcc.calculate.Calculator;
import xyz.lyhcc.calculate.MathCalculator;
import xyz.lyhcc.proxy.ProxyCalculator;

public class ProxyTest {
@Test
public void test() {
Calculator proxy = (Calculator) ProxyCalculator.getProxy(new MathCalculator());
proxy.add(1,2);
proxy.div(10, 2);
}
}

代理获取类ProxyCalculator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import xyz.lyhcc.calculate.Calculator;
import xyz.lyhcc.logger.LoggerUtils;

public class ProxyCalculator {
public static Calculator getProxy(Calculator calculator) {

ClassLoader loader = calculator.getClass().getClassLoader();
Class<?>[] interfaces = calculator.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


Object result = null;
try {
LoggerUtils.logStart(method, args);
result = method.invoke(calculator, args);
LoggerUtils.logFinished(method, result);
} catch (Exception e) {
LoggerUtils.logError(method, e);
}


return result;
}
};
Object proxy = Proxy.newProxyInstance(loader, interfaces, h);
return (Calculator) proxy;
}
}

日志类 LoggerUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.lang.reflect.Method;
import java.util.Arrays;

public class LoggerUtils {
public static void logStart(Method method, Object... args) {
System.out.println("[" + method.getName() + " is running..] args=" + Arrays.asList(args));
}
public static void logFinished(Method method, Object result) {
System.out.println("[" + method.getName() + " is Finished...] result=" +result);
}
public static void logError(Method method, Exception e) {
System.out.println("[" + method.getName() + " has errors] error is " + e.getCause());
}

}

计算器类和接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public interface Calculator {
public int add(int x, int y);
public int sub(int x, int y);
public int multi(int x, int y);
public int div(int x, int y);
}

public class MathCalculator implements Calculator{

@Override
public int add(int x, int y) {
return x + y;
}

@Override
public int sub(int x, int y) {
return x - y;
}

@Override
public int multi(int x, int y) {
return x * y;
}

@Override
public int div(int x, int y) {
return x / y;
}

}

动态代理的问题

  1. 当没有实现任何接口时无法使用动态代理,代理对象和被代理对唯一能产生的关联就是实现了同一接口
  2. 实现起来困难

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×