初识代理的时候,大家是否有这样的疑惑呢?什么是代理,想必大家都是有一定了解的,那么怎么在编程代码中实现代理呢?也许有很多人是不太了解的,在这里,听我娓娓道来。
代理的概念:
生活中的代理是很常见的,比如代购、律师、中介等,他们都有一个共性就是帮助被代理人处理一些前前后后的事情。而被代理人只需要专注做自己要做的那部分事情就可以了。
该图片描述了生活中一些常见的代理。
Java中的代理也是类似的,代理模式可以实现帮助被代理者完成一些前期的准备工作和后期的善后工作,但是核心的业务逻辑仍然是由被代理者完成。
它分为两类一个是静态代理,一个是动态代理
#什么是静态代理呢?
静态代理模式由三个部分构成:
.一个公共的接口
.一个代理角色
.被代理角色(可以有多个)
例如:
现在我定义一个公共的接口
interface cothFactory{
abstract public void product();//用做与生产不同种类的衣服
}
之后定义一个类实现这个类接口
class ProxycothFactory implements cothFactory{
private cothFactory coth;//接口类对象,但是没有实例化,用于实现多态
public ProxycothFactory(cothFactory coth) {//构造器,用于生成对象
super();
this.coth = coth;
}
@Override
public void product() {//实现重写
System.out.println("开始选择商家生产....");
coth.product();//多态的那个对象的重写方法
System.out.println("生产好了...");
}
}
之后定义一个具体工厂实现重写函数
class NickFactory implements cothFactory{
@Override
public void product() {
System.out.println("这是耐克生产的鞋子....");
}
}
之后在测试中写
public class 静态代理 {
public static void main(String[] args) {
ProxycothFactory pro=new ProxycothFactory(new NickFactory());
pro.product();
}
}
就完成了静态代理
完整代码如下:
package 代理;
interface cothFactory{
abstract public void product();
}
class ProxycothFactory implements cothFactory{
private cothFactory coth;
public ProxycothFactory(cothFactory coth) {
super();
this.coth = coth;
}
@Override
public void product() {
System.out.println("开始选择商家生产....");
coth.product();
System.out.println("生产好了...");
}
}
class NickFactory implements cothFactory{
@Override
public void product() {
System.out.println("这是耐克生产的鞋子....");
}
}
public class 静态代理 {
public static void main(String[] args) {
ProxycothFactory pro=new ProxycothFactory(new NickFactory());
pro.product();
}
}
结果如图:
想必大家现在对静态代理有点一定了解了吧。
但是你们有想过一个问题吗?该代理是我们知道是哪个代理类的,并只针对该产品代理的,那么如何实现一个代理工厂实现不同的代理类对象呢?这就是我们下面要讲的动态代理
#什么是动态代理?
动态代理设计模式的核心特点:一个代理类可以代理所有需要被代理接口的子类对象。
例如:
如果要想进行动态代理设计的实现,代理类不再具体实现于某一个接口。
我们需要实现InvocationHandler动态代理实现标识接口,只有实现此接口的子类才具备动态代理的功能。
public Object invoke(Object proxy, Method method, Object[] args);
invoke()表示的是调用执行的方法,但是所有的代理类返回给用户的接口对象都属于代理对象,当用户执行接口方法的时候所调用的实例化对象就是该代理主题动态创建的一个接口对象。
proxy 表示的是被代理的对象信息。
method 返回的是被调用的方法对象,取得了Method对象意味着可以使用invoke()反射调用方法。
args 标识方法中收到的参数
class myProxy implements InvocationHandler{
public Object obj;
public void getObj(Object obj)
{
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object v=method.invoke(obj, args);
return v;
}
}
如果要想进行对象的绑定,那么就需要使用到一个Proxy的程序类,这个程序类的主要功能是可以绑定所有的你需要绑定的接口子类的对象,而且这些对象都是根据接口自动创建的,该类有一个动态创建的方法(该方法在Java源码中有明确描述,使用时,我们就直接调用即可):
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
Objects.requireNonNull(h);
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);
}
}
}
实现真实对象的绑定处理,同时返回代理对象。(这个对象是根据接口定义动态创建形成的代理对象)。
class ProxyFactory{
public static Object getProxyInstance(Object obj)
{
myProxy hander=new myProxy();
hander.getObj(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hander);
}
}
完整代码实现超人代理和cothFactory代理
如下:
package 代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Human{
abstract public void eat(String s);
abstract public void getBilif();
}
class superMan implements Human{
@Override
public void eat(String s) {
System.out.println("超人喜欢吃"+s);
}
@Override
public void getBilif() {
System.out.println("I believe I can fly!");
}
}
class ProxyFactory{
public static Object getProxyInstance(Object obj)
{
myProxy hander=new myProxy();
hander.getObj(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hander);
}
}
class myProxy implements InvocationHandler{
public Object obj;
public void getObj(Object obj)
{
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object v=method.invoke(obj, args);
return v;
}
}
public class 动态代理 {
public static void main(String[] args) {
superMan man=new superMan();
Human human=(Human)ProxyFactory.getProxyInstance(man);
human.eat("icestream");
human.getBilif();
System.out.println(".............................");
NickFactory nick=new NickFactory();
cothFactory co=(cothFactory)ProxyFactory.getProxyInstance(nick);
co.product();
}
}
结果:如下:
最后,这里代理就告一段落了。
中:谢谢大家的阅读,如有见解欢迎评论,我会加以改进。
英:Thank you for reading. Thank you for reading. If you have any opinions, please comment. I will improve it.
俄:Спасибо за чтение, спасибо за чтение, если есть идеи приветствие комментарии, я буду их пересмотр.