背景
最近在处理一个生产问题的时候,看到依赖的三方库中用到了javassit 作为动态代理,然后就着手学习了javassit作为动态代理的实现。
但是网上很多的例子都是错误, 比如有些例子,既然是做动态代理,生产代理的时候,居然不需要使用被代理对象, 我也是醉了。
动态代理有如下几个对象
- 被代理对象
- 代理对象(动态生成的,也是代理工厂产生的)
- 代理增强
- 代理工厂(可以没有)
废话不多说,直接撸代码。
javaassit版本
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
被代理对象
public class Target {
public int count = 10;
public Target setCount(int count) {
this.count = count;
return this;
}
public void test1(){
throw new RuntimeException("test throw exception");
}
public void test2(){
System.out.println("test2 success");
}
}
代理增强
import javassist.util.proxy.MethodHandler;
public abstract class Aop implements MethodHandler {
private Object target;
public Aop(Object target) {
this.target = target;
}
public Object getTarget() {
return target;
}
}
//////////////////////////////////////////////////////////////////////////////
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
public class LogAop extends Aop {
private static Logger logger = LoggerFactory.getLogger(LogAop.class);
public LogAop(Object target) {
super(target);
}
@Override
public Object invoke(Object proxy, Method targetMethod, Method proxyMethod, Object[] args)
throws Throwable {
String resultMessage = "Fail";
Long startTime = System.currentTimeMillis();
logger.info("enter method:" + targetMethod.getName());
try {
Object ret = targetMethod.invoke(getTarget(), args);
resultMessage = "Success";
return ret;
}finally {
logger.info("exist ["+resultMessage+"] method:" + targetMethod.getName()+", cost "+ (System.currentTimeMillis()-startTime)+" ms");
}
}
}
代理工厂
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
public class JavassistProxyFactory<T> {
public T getProxy(Aop aop) throws IllegalAccessException, InstantiationException {
ProxyFactory proxyFactory = new ProxyFactory();
// 让代理类继承自目标类。
proxyFactory.setSuperclass(aop.getTarget().getClass());
Class<ProxyObject> classes=proxyFactory.createClass();
//创建代理对象
ProxyObject proxyObject=classes.newInstance();
//为代理类设置
proxyObject.setHandler(aop);
// 通过字节码技术动态创建子类实例
return (T) proxyObject;
}
}
测试类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
private static Logger logger = LoggerFactory.getLogger(LogAop.class);
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
JavassistProxyFactory<Target> factory = new JavassistProxyFactory<>();
Target target = new Target();
target.setCount(100);
LogAop aop = new LogAop(target);
Target proxy = factory.getProxy(aop);
try {
proxy.test1();
}catch (Exception e) {
logger.error("删除失败", e);
}
try {
proxy.test2();
}catch (Exception e) {
logger.error("保存失败", e);
}
}
}
网友评论