文章目录
前言
代理模式就是当客户端想要调用被代理类的方法时,不是直接调用被代理类的方法,而是通过被代理类的委托类来实现,也就是说客户端调用委托类,委托类再调用被代理类。这样做的好处是我们可以在委托类中在执行被代理类方法之前和之后进行相关的处理,而不去影响被代理类中的相关业务代码。
代理分为两种,静态代理和动态代理。动态代理有可分为JDK动态代理和CGLib动态代理。
- 静态代理:在代码编译前已经知道代理的是哪个对象。
- 动态代理:在代码编译前不知道代理的是哪个对象,在执行时才会知道。
- JDK动态代理:被代理的对象必须有接口,而且只能代理接口中存在的方法。
- CGLib动态代理:被代理的对象无需拥有接口,但是必须能够被继承。
CGLib动态代理的优点是被代理类不需要接口,因为在实际开发中不一定每个类都需要接口。
静态代理
类图
- Subject : 被代理类接口
- RealSubject : 被代理类的实现类
- doSomething() :需要被代理的方法
- Proxy : 代理类,也是实现Subject接口
- before():在被代理方法执行前执行
- after():在被代理方法执行后执行
代码实现
- Subject : 被代理类接口
public interface Subject {
void doSomething();
}
- RealSubject : 被代理类的实现类
public class RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("我正在执行被代理类的方法。。。。");
}
}
- Proxy : 代理类,也是实现Subject接口
public class Proxy implements Subject {
private Subject subject = null;
public Proxy(Subject subject){
this.subject = subject;
}
@Override
public void doSomething() {
before();
this.subject.doSomething();
after();
}
private void before(){
System.out.println("我是代理类,正在执行before()");
}
private void after(){
System.out.println("我是代理类,正在执行after()");
}
}
- 客户端调用
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy(new RealSubject());
proxy.doSomething();
}
}
- 输出
我是代理类,正在执行before()
我正在执行被代理类的方法。。。。
我是代理类,正在执行after()
Java动态代理
代码实现
- Subject 被代理类的接口
public interface Subject {
String doSomething();
}
- RealSubject 被代理类的实现类
public class RealSubject implements Subject {
@Override
public String doSomething() {
System.out.println("我正在执行被代理类的方法。。。。");
return "success!";
}
}
- MyInvocationHandler
public class MyInvocationHandler implements InvocationHandler {
private Object target = null;
public MyInvocationHandler(Object object){
this.target = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object ret = method.invoke(this.target,args);
after();
return ret;
}
private void before(){
System.out.println("我是代理类,正在执行before()");
}
private void after(){
System.out.println("我是代理类,正在执行after()");
}
}
- MyProxy
public class MyProxy {
private Object target = null;
private InvocationHandler handler = null;
public MyProxy(InvocationHandler handler,Object target){
this.handler = handler;
this.target = target;
}
Object getProxy(){
Object object = Proxy.newProxyInstance(
this.target.getClass().getClassLoader(),
this.target.getClass().getInterfaces(),
this.handler);
return object;
}
}
- Client
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
MyInvocationHandler handler = new MyInvocationHandler(subject);
Subject proxy = (Subject)new MyProxy(handler,subject).getProxy();
System.out.println("返回值 = " + proxy.doSomething()); ;
}
}
- 输出
我是代理类,正在执行before()
我正在执行被代理类的方法。。。。
我是代理类,正在执行after()
返回值 = success!
实现原理
java.lang.reflect.InvocationHandler接口
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
java.lang.reflect.Proxy.newProxyInstance类
- loader:类加载器
- interfaces:被代理类的接口
- InvocationHandler:InvocationHandler实现类
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
//InvocationHandler是否为null ,是则抛出异常 NullPointerException
Objects.requireNonNull(h);
//由于没有设置安全管理器,返回的是null
final Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
/*
* Look up or generate the designated proxy class and its constructor.
*/
//获取动态代理类的构造器
Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
return newProxyInstance(caller, cons, h);
}
//最终调用的是这个方法来获取代理类
private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager
Constructor<?> cons,
InvocationHandler h) {
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (caller != null) {
checkNewProxyPermission(caller, cons.getDeclaringClass());
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
}
}
CGLib动态代理
代码实现
- RealSubject 被代理类
public class RealSubject {
public String doSomething() {
System.out.println("我正在执行被代理类的方法。。。。");
return "success!";
}
}
- CglibProxy 代理类
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(o,args);
after();
return result;
}
private void before(){
System.out.println("我是代理类,正在执行before()");
}
private void after(){
System.out.println("我是代理类,正在执行after()");
}
}
- Client 客户端
public class Client {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
RealSubject proxy = (RealSubject)cglibProxy.getProxy(RealSubject.class);
System.out.println("返回值 = " + proxy.doSomething()); ;
}
}
- 输出
我是代理类,正在执行before()
我正在执行被代理类的方法。。。。
我是代理类,正在执行after()
返回值 = success!