- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- AOP编程操作的主要对象是切面(aspect),而切面用于模块化横切关注点(公共功能)。
使用JDK动态代理实现日志的打印
package com.longli.spring.aop.beans;
public interface Calculator {
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
int div(int a,int b);
}
package com.longli.spring.aop.beans;
import org.springframework.stereotype.Component;
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
int result =a+b;
return result;
}
@Override
public int sub(int a, int b) {
int result =a-b;
return result;
}
@Override
public int mul(int a, int b) {
int result =a*b;
return result;
}
@Override
public int div(int a, int b) {
int result =a/b;
return result;
}
}
package com.longli.spring.log;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class LoggingProxy {
//被代理对象
private Object target;
public LoggingProxy(Object target) {
this.target = target;
}
public Object getProxy(){
//获取被代理对象的加载器
ClassLoader classLoader = target.getClass().getClassLoader();
//实现被代理对象的接口们
Class<?>[] interfaces = target.getClass().getInterfaces();
Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
/**
* 这里用到了匿名类部类
* invoke方法就是要执行的扩展控制功能
* @param proxy :被代理对象
* @param method:要调用方法
* @param args:调用方法传入的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取方法名
String methodName = method.getName();
System.out.println("logging:The method "+methodName+" begin with"+ Arrays.toString(args));
//执行目标,即将方法的调用转到代理对象上
Object result = method.invoke(target, args);
System.out.println("Logging:The method "+methodName+" return "+result);
return result;
}
});
return proxy;
}
}
/**
* 测试代理对象
*/
@Test
public void testLoggingProxy(){
Calculator calculator=new CalculatorImpl();
//获取代理对象
Calculator calculator1 = (Calculator) new LoggingProxy(calculator).getProxy();
int add = calculator1.add(10, 2);
System.out.println(add);
int sub = calculator1.sub(10, 2);
System.out.println(sub);
int mul = calculator1.mul(10, 2);
System.out.println(mul);
int div = calculator1.div(10, 2);
System.out.println(div);
}