代理模式
什么是代理
让我们假设一个场景,比如国内的酒厂想要在国外买酒,拓展新的业务。但是酒厂只提供酒,别的不管。这个时候就要找一个代理商,来进行销售。这个就是代理模式。
java中的代理模式分为几种?
可以分为静态代理与动态代理两种。
静态代理
静态代理主要是在编写代码时由我们手动编写代理类去实现拓展的功能,之所以称之为静态,是因为所有的代理关系全部都是固定死的。
动态代理
动态代理相对于静态代理,最大的变化就是不用手动去实现自己的代理类了,只需要通过JDK或者CGLIB去获得一个代理类,而代理类是在运行时被生成与加载的。
静态代理的实现
实例 :儿子大龄单身狗,没时间找对象,父亲要帮儿子找对象(父亲充当代理者)
package com.example.demo.demo.proxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe
**/
public interface IPserson {
/**
* 寻找对象
*/
void findWife();
}
package com.example.demo.demo.proxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe 大龄单身狗,到了结婚的年级,走相亲路线
**/
public class FindLoverPerson implements IPserson{
@Override
public void findWife() {
System.out.println("肤白貌美大长腿的对象");
}
}
package com.example.demo.demo.proxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe 父亲给孩子物色对象
**/
public class FindLovePersonFather implements IPserson{
private FindLoverPerson findLoverPerson ;
public FindLovePersonFather(FindLoverPerson findLoverPerson) {
this.findLoverPerson = findLoverPerson;
}
@Override
public void findWife() {
System.out.println("老爹开始物色对象");
findLoverPerson.findWife();
System.out.println("牵手成功");
}
}
package com.example.demo.demo.proxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe 父亲给儿子物色对象
**/
public class test {
public static void main(String[] args) {
FindLovePersonFather findLovePersonFather = new FindLovePersonFather(new FindLoverPerson());
findLovePersonFather.findWife();
}
}
动态代理实现
还是单身狗例子:儿子大龄单身狗,没时间找对象,父亲委托媒婆要帮儿子找对象(媒婆充当代理者,专业的人办理专业的事情)
package com.example.demo.demo.design.link.dyproxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe
**/
public interface IPserson {
/**
* 找人介绍对象
*/
void findWife();
}
package com.example.demo.demo.design.link.dyproxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe 大龄单身狗,到了结婚的年级,走相亲路线
**/
public class FindLoverPerson1 implements IPserson {
@Override
public void findWife() {
System.out.println("肤白貌美大长腿的对象,主要是高" +
"");
}
}
package com.example.demo.demo.design.link.dyproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe
**/
public class JdkMeiPoProxy implements InvocationHandler {
private Object object ;
public Object getInstance(Object object ){
this.object=object;
Class<?> clazz = object.getClass();
//newProxyInstance 内的参数lazz.getClassLoader(),clazz.getInterfaces()
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
/**
*proxy 代理对象 ,method代理方法,args参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(object, args);
after();
return invoke;
}
private void after() {
System.out.println("双方同意,开始交往");
}
private void before() {
System.out.println("我是媒婆,已经得到了你的要求,正在给你物色对象");
}
}
package com.example.demo.demo.design.link.dyproxy;
/**
* @author wangjian
* @createDate 2021/3/22
* @describe
**/
public class DyTest {
public static void main(String[] args) {
JdkMeiPoProxy jdkMeiPoProxy = new JdkMeiPoProxy();
IPserson instance = (IPserson)jdkMeiPoProxy.getInstance(new FindLoverPerson());
instance.findWife();
IPserson instance1 = (IPserson)jdkMeiPoProxy.getInstance(new FindLoverPerson1());
instance1.findWife();
}
}
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
// 将参数传进来的接口克隆:intfs
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
* class com.sun.proxy.$Proxy0
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 得到对应的构造方法 =public com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 最终生成一个对象
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);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}