欢迎大家下载我个人开发的app安琪花园
定义
通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
- 通过预编译的方式(比如: AspectJ)
- 通过运行时动态代理 ( Proxy.newInstance() )
AOP的 好处
降低耦合度, 通用代码的复用
动态代码的关键类
- Proxy
- InvocationHandler
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
proxy: 指代生成的代理的对象
method:指我们调用真实对象的某个方法
args: 指调用某个真实对象方法的参数
动态代理的条件
- 被代理的对象必须要实现某一个或者多个接口
具体的使用
- 首先定义一个接口
public interface Subject {
public void sayGoodBye();
public void sayHello(String str);
}
- 写一个实体类继承自上面的这个接口
public class RealSubject implements Subject {
@Override
public void sayGoodBye() {
System.out.println("RealSubject sayGoodBye");
}
@Override
public void sayHello(String str) {
System.out.println("RealSubject sayHello " + str);
}
}
- 自定义Invocationhandler
public class SubjectInvocationHandler implements InvocationHandler {
//这个就是我们要代理的真实对象
private Object subject;
//构造方法,给我们要代理的真实对象赋初值
public SubjectInvocationHandler(Object subject) {
this.subject = subject;
}
@Override
public Object invoke(Object object, Method method, Object[] args) throws Throwable {
//在代理真实对象前我们可以添加一些自己的操作
System.out.println("before Method invoke");
System.out.println("Method:" + method);
//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(subject, args);
//在代理真实对象后我们也可以添加一些自己的操作
System.out.println("after Method invoke");
return null;
}
}
- 具体的使用
//被代理类
Subject realSubject = new RealSubject();
//我们要代理哪个类,就将该对象传进去,最后是通过该被代理对象来调用其方法的
SubjectInvocationHandler handler = new SubjectInvocationHandler(realSubject);
//生成代理类
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
- 当调用第四步里面rrealSubject里面的方法的时候 就会转到Invocationhander里面的invoke方法
以上就是动态代理的简单实现步骤
原理
最近对动态代理的原理进行了了解。
-
当调用Proxy.newProxyInstance方法的时候,就会生成代理类对象,
其名字的格式为 $Proxy + 数字的形式, 继承自Proxy, 并且实现了代理的接口。 -
当调用方法的时候,则调用代理对象的方法,通过对生成的代理对象的代码阅读。
代理对象实现 了接口,重写了接口的方法,方法体为 InvocationHandler调用这个方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
公众号:
网友评论