版权声明:如果觉得文章对你有用,转载不需要联系作者,但请注明出处 https://blog.csdn.net/jinxin70/article/details/82949805
Java动态代理
如果你已经了解代理模式,但是不知道Java动态代理的实现,可以阅读本文,必须自己动手写一遍,并运行。但即使这样操作后你的水平也只是用过Java动态代理而已,具体的内部实现,需要debug进源码进行分析。
1、定义一个公共接口Greeting.java:
package aop;
public interface Greeting {
void sayHello(String name);
}
2、定义真实业务逻辑类GreetingImpl.java,实现Greeting接口,重写sayHello方法:
package aop.demo3;
import aop.Greeting;
public class GreetingImpl implements Greeting {
public void sayHello(String name) {
System.out.println("Hello! " + name);
}
}
3、定义代理类JDKDynamicProxy的逻辑,实现InvocationHandler接口,重写invoke方法,在invoke中添加额外逻辑before()和after(),并调用真实业务方法method.invoke(target,args);
调用Proxy.newProxyInstance方法生成代理类对象,客户端实际使用的是这个对象:
package aop.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKDynamicProxy implements InvocationHandler {
private Object target;
public JDKDynamicProxy(Object target) {
this.target = target;
}
//生成代理对象,传入真实业务类的classloader、真实业务类实现的接口、InvocationHandler
@SuppressWarnings("unchecked")
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
//增强真实业务类的调用
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}
4、客户端使用动态代理,通过构造器注入真实业务类对象,调用getProxy方法获得代理类对象,调用代理方法sayHello:
package aop.demo3;
import aop.Greeting;
/**
* 3. JDK 动态代理
*/
public class Client {
public static void main(String[] args) {
Greeting service = new GreetingImpl();
Greeting greeting = new JDKDynamicProxy(service).getProxy();
greeting.sayHello("Jack");
}
}
5、执行结果:
下一篇,深入Java动态代理原理
一些问题:
Java动态代理只能代理接口,不能代理没有接口的类。(为什么只能代理接口?从Proxy.newProxyInstance可以看出,这个方法是生成代理类对象用的,第二个参数要求传递真实业务类的接口,并且最终生成的代理类和真实业务类实现了同样的接口。更具体的细节,看下一篇Java动态代理原理分析就知道了)
假如我想要增强一个没有接口的类,怎么办呢?CGLib类库可以代理没有接口的类。
参考文章及案例代码:
https://www.jianshu.com/p/a1d094fc6c00 参考了该文章的行文逻辑