基于CGLIB手动实现动态代理例子完整代码
预定流程
图4-1所示的约定流程如下。
(1)调用拦截器的before()方法;
(2)调用目标方法;
(3)调用目标方法时如果发生异常,则调用afterThrowing()方法;
(4)调用目标方法时如果未发生异常,则调用afterReturning()方法;
(5)调用after()方法;
(6)如果拦截器的useAround()方法返回true,用拦截器的around()方法取代上面的整个流程。
代码结构
目标对象接口-HelloService
package com.burns.test.test3;
/**
* 这个接口很简单,就是定义一个sayHello()方法,其中的参数name是名字,这样就可以对该名字说hello了
*/
public interface HelloService {
public void sayHello(String name);
}
目标对象接口实现类-HelloServiceImpl
package com.burns.test.test3;
/**
* 这里的代码也很简单,方法sayHello()先判断name是否为空。
* 如果为空,则抛出异常,告诉调用者参数为空;
* 如果不为空,则对该名字说hello。
* 这样,一个非常简单的服务就写好了
*/
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello(String name) {
if (name == null || "".equals(name.trim())) {
throw new RuntimeException("parameter is null!!");
}
System.out.println("hello " + name);
}
}
拦截器接口-Interceptor
package com.burns.test.test3;
/**
* 一个拦截器接口,它十分简单,只包含几个方法
*/
public interface Interceptor {
// 事前方法
public void before();
// 事后方法
public void after();
/**
* 取代原有事件方法
*
* @param invocation -- 回调参数,可以通过它的proceed()方法回
* 调原有事件
* @return 原有事件返回对象
* @throws Throwable
*/
public Object around(Invocation invocation) throws Throwable;
// 事后返回方法,事件没有发生异常时运行
public void afterReturning();
// 事后异常方法,事件发生异常后运行
public void afterThrowing();
// 是否使用around()方法取代整个流程,默认为false
public default boolean useAround() {
return false;
}
}
拦截器接口实现类-MyInterceptor
package com.burns.test.test3;
/**
* 根据拦截器接口的定义来开发一个自己的拦截器——MyInterceptor
*/
public class MyInterceptor implements Interceptor {
@Override
public void before() {
System.out.println("before ......");
}
@Override
public boolean useAround() {
return true;
}
@Override
public void after() {
System.out.println("after ......");
}
@Override
public Object around(Invocation invocation) throws Throwable {
System.out.println("around before ......");
Object obj = invocation.proceed();
System.out.println("around after ......");
return obj;
}
@Override
public void afterReturning() {
System.out.println("afterReturning......");
}
@Override
public void afterThrowing() {
System.out.println("afterThrowing......");
}
}
回调参数-Invocation
package com.burns.test.test3;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Invocation {
private Object[] params; // 参数
private Method method; // 方法
private Object target; // 目标对象
private Interceptor interceptor; // 拦截器
public Invocation(Object target,
Method method, Object[] params, Interceptor interceptor) {
this.target = target;
this.method = method;
this.params = params;
this.interceptor = interceptor;
}
// 反射方法
public Object proceed() throws InvocationTargetException, IllegalAccessException {
Object retObj = null; // 返回结果
boolean exceptionFlag = false; // 异常标志位
// 调用拦截器的before()方法
this.interceptor.before();
try {
// 使用反射调用原有方法,并保存返回值
retObj = method.invoke(target, params);
} catch (Exception ex) {
// 设置异常标志位
exceptionFlag = true;
}
if (exceptionFlag) { // 发生异常则运行拦截器的afterThrowing()方法
this.interceptor.afterThrowing();
} else { // 未发生异常则运行拦截器的afterReturning()方法
this.interceptor.afterReturning();
}
// 无论发生异常与否,都会运行的拦截器after()方法
this.interceptor.after();
return retObj;
}
/**** setters and getters ****/
}
代理类-ProxyBean
package com.burns.test.test3;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyBean implements MethodInterceptor {
// 拦截器
private Interceptor interceptor = null;
// 目标对象
private Object target = null;
/**
* 生成代理对象
*
* @param target 目标对象
* @param interceptor 拦截器
* @return 代理对象
*/
public static Object getProxy(Object target, Interceptor interceptor) {
ProxyBean proxyBean = new ProxyBean();
// 创建增强者
Enhancer enhancer = new Enhancer();
// 设置代理的类
enhancer.setSuperclass(target.getClass());
// 设置代理对象可以下挂到哪些接口下
enhancer.setInterfaces(target.getClass().getInterfaces());
// 保存目标对象
proxyBean.target = target;
// 保存拦截器
proxyBean.interceptor = interceptor;
// 设置代理对象为proxyBean,运行时会回调代理对象的intercept() 方法
enhancer.setCallback(proxyBean); // ①
// 创建动态代理对象
Object proxy = enhancer.create();
return proxy;
}
/**
* 代理对象逻辑
*
* @param proxy 代理对象
* @param method 拦截器的方法
* @param args 方法参数
* @param mproxy 方法代理
* @return 返回目标方法和对象
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args
, MethodProxy mproxy)
throws Throwable {
// 回调对象
Invocation invocation =
new Invocation(this.target, method, args, this.interceptor);
Object result = null;
if (this.interceptor.useAround()) { // 是否启用环绕通知
result = this.interceptor.around(invocation);
} else {
result = invocation.proceed();
}
// 返回结果
return result;
}
}
测试类-AopTest
package com.burns.test.test3;
public class AopTest {
public static void main(String[] args) {
testProxy();
}
public static void testProxy() {
// 目标对象
HelloService helloService = new HelloServiceImpl();
// 获取代理对象,绑定流程
HelloService proxy = (HelloService) ProxyBean.getProxy(
helloService, new MyInterceptor());
// 调用方法,该方法将被织入约定的流程中
proxy.sayHello("张三");
System.out.println("###############测试异常###############");
// 调用方法,测试异常情况
proxy.sayHello(null);
}
}
输出
around before ......
before ......
hello 张三
afterReturning......
after ......
around after ......
###############测试异常###############
around before ......
before ......
afterThrowing......
after ......
around after ......
最后-完整代码例子参考下载
https://download.csdn.net/download/zp357252539/90542223