有时候我们希望在不改变源码的情况下,对一些代码的功能进行增强,往往这些增强的功能是一些附加功能,如执行的日志,出错信息等。
- 在目标类源代码不改变的情况下,增加功能
- 减少代码的重复
- 专注业务逻辑代码
- 解耦合,让你的业务功能和非业务功能(日志)分离
jdk动态代理必须有接口。
定义如下包含两个方法的接口ISomeService
public interface ISomeService {
void doSome();
void doOther();
}
定义实现这个接口的类SomeServiceImpl
public class SomeServiceImpl implements ISomeService{
@Override
public void doSome() {
System.out.println("执行业务方法doSome");
}
@Override
public void doOther() {
System.out.println("执行业务方法doOther");
}
}
设置一个专门的类ServiceTools
,在该类里面添加增强的方法,可以将该方法定义为静态
public class ServiceTools {
public static void doLog(){
System.out.println("非业务方法,执行方法时间"+new Date());
}
public static void doTrans(){
System.out.println("方法执行完毕,提交事务");
}
}
定义自己的MyInvocationHandler
实现InvocationHandler
接口
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//通过代理对象执行方法是,会调用执行这个invoke()
Object res=null;
ServiceTools.doLog();
//执行目标类的方法,通过Method类实现
res=method.invoke(target,args);
ServiceTools.doTrans();
return res;
}
}
设置一个测试的主函类MyApp
public class MyApp {
public static void main(String[] args) {
//使用jdk的Proxy创建代理对象
//创建目标对象
SomeServiceImpl target=new SomeServiceImpl();
//创建InvocationHandler对象
InvocationHandler handler=new MyInvocationHandler(target);
//使用proxy创建代理
ISomeService proxy= (ISomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),handler);
//通过代理执行方法,会调用handler中的invoke()方法
proxy.doSome();
}
}
我们可以得到如下执行结果:
非业务方法,执行方法时间Fri Jul 24 22:24:35 CST 2020
执行业务方法doSome
方法执行完毕,提交事务
网友评论