Spring里最重要的两个特性就当属IOC和AOP吧,对于AOP的原理最近看书自我感觉理解了不少,在此还是做个笔记记录一下,不要只有嘴上功夫。
直接通过一个例子来说明吧,本人组织能力不太行,从别人那复制粘贴过来也没啥意思,懂的都懂,感觉没啥必要哈哈哈哈哈哈哈哈
- 先创建一个简单的接口和它的实现类
//使用的是JDK自带的方法生成代理对象实现切面的效果,因此接口是不能少的,不用接口的那个CGLIB,那个以后看看吧
public interface HelloService {
void hello(String name);
}
public class HelloServiceImpl implements HelloService {
@Override
public void hello(String name) {
//加了个抛异常方便后面模拟出异常的调用的切面方法
if (StringUtils.isEmpty(name)) {
throw new RuntimeException("name is null!");
}
System.out.println("hello "+name);
}
}
- 定义Invocation类,它用是于实现环绕通知功能的一个类,主要就是通过反射进行作用
public class Invocation {
private Object[] params;
private Method method;
private Object target;
public Invocation(Object[] params, Method method, Object target) {
this.params = params;
this.method = method;
this.target = target;
}
//getset方法省略
}
- 定义拦截器接口以及实现类
public interface Interpector {
boolean before();
void after();
Object around(Invocation invocation);
void afterReturning();
void afterThrowing();
boolean useAround();
}
public class MyInterceptor implements Interpector{
@Override
public boolean before() {
System.out.println("before..............");
return true;
}
@Override
public void after() {
System.out.println("after...............");
}
@Override
public Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("around before.......");
Object obj = invocation.proceed();
System.out.println("around after........");
return obj;
}
@Override
public void afterReturning() {
System.out.println("after returning.....");
}
@Override
public void afterThrowing() {
System.out.println("after throwing......");
}
@Override
public boolean useAround() {
return true;
}
}
- 生成代理对象的工具类
//注意这个实现了JDK自带的InvocationHandler接口
public class ProxyCreator implements InvocationHandler {
private Object target;
private Interceptor interceptor;
//在下面这个重写的方法里写好具体切面怎么切
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean exceptionFlag = false;
Invocation invocation = new Invocation(target, method, args);
interceptor.before();
Object returnObj = null;
try {
if (interceptor.useAround()) {
returnObj = interceptor.around(invocation);
} else {
returnObj = method.invoke(target, args);
}
} catch (Exception e) {
exceptionFlag = true;
}
interceptor.after();
if (exceptionFlag) {
interceptor.afterThrowing();
}else {
interceptor.afterReturning();
return returnObj;
}
return null;
}
public static Object getProxyBean(Object target, Interceptor interceptor) {
ProxyCreator proxyCreator = new ProxyCreator();
proxyCreator.target = target;
proxyCreator.interceptor = interceptor;
//JDK自带的静态方法,用它可以生成代理对象,三个参数为:类加载器、绑定的接口,实现了InvocationHandler接口的一个类的对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyCreator);
}
}
- 简单写一个测试类测试一下
public class AOPTest {
HelloService helloService;
@Before
public void getProxyObj(){
helloService = (HelloService) ProxyCreator.getProxyBean(new HelloServiceImpl(), new MyInterceptor());
}
@Test
public void test_name_is_not_null(){
helloService.hello("world");
}
@Test
public void test_name_is_null(){
//null或者空字符串都可以
helloService.hello(null);
}
}
结果如下
#test_name_is_not_null
before..............
around before.......
hello world
around after........
after...............
after returning.....
#test_name_is_null
before..............
around before.......
after...............
after throwing......