First analyze the three roles in the dynamic proxy model:
1. Abstract role: In static proxy it can be an abstract class, but in dynamic proxy it can only be an interface
2. Real role: It just implements the methods in the abstract role.
3. Agent role: The most disgusting thing is the agent role in the dynamic agent. It should hold a reference to the real character.
It involves an interface and a class, the InvocationHandler interface and the Proxy class. According to the JDK documentation, the InvocationHandler interface is implemented by a class, and an instance of this class is the handler object corresponding to a proxy object. When a method of the proxy object is called, the method will be encoded and assigned to the invoke method of its corresponding handler object to call!
Copy the code code as follows:
//Abstract role:
public interface AbstractRole
{
public void show();
}
//Real character:
public class RealRole implements AbstractRole
{
@Override
public void show(){ System.out.println("show me your house"); }
}
//Agent role:
//I think this is just a pseudo-agent. I came up with the pseudo-agent myself = =! , because it is actually the handler corresponding to the agent
public class Handler implements InvocationHandler
{
private Object realRole; // The proxy role needs to have a reference to the real role. If it is defined as Object type, it is universal.
public Handler(Object realRole)
{ this.realRole = realRole; }
@Override
public Object invoke(Object proxy, Method method, Object[] args)
{
System.out.println("Give me your money"); // This is an additional function added by the agent role itself.
method.invoke(this.realRole, args); //Invoke the real role's method through reflection
System.out.println("Ok...house is yours");//This is an additional function added by the agent role itself.
}
public Object factory()//Generate the real agent role through the factory method
{
return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.realObject.getClass().getInterfaces(), this); //The newProxyInstance method in Proxy has two very important features! The first is to dynamically create a proxy class, if the output seems to be a class named $Proxy0; the second is to generate an instance through the dynamically created class.
}
}
//Client:
public class Test
{
public static void main(String[] args)
{
RealRole realRole = new RealRole();//Which real role you want to represent, just create a new real role
Handler handler = new Handler(realRole);//The handler corresponding to the proxy class is generated here. I also want to call it a pseudo-proxy object.
AbstractRole proxy = (AbstractRole)handler.factory();//Generate proxy objects through factory methods
}
}
You may be wondering how the agent role here can be forcibly converted into an abstract role? The reason lies in the newProxyInstance method. This method is too interesting. As mentioned above, it will automatically generate a class and then generate a proxy object through the class. In fact, this class implements the abstract role class. Why? Because the second parameter has already specified which interfaces it implements. So you can force the transfer. After the force transfer, you can call the methods in the abstract role.
proxy.show();//Okay! Pay attention to this sentence. I marked it in red at the beginning, "This method will be encoded and assigned to the invoke method of its corresponding handler object to call!" Because of this sentence, proxy.show() The show method is passed to the invoke method in the handler object. Of course, the parameters of the show method are also followed, but the show method here has no parameters. So the sentence proxy.show() actually calls the invoke method in the handler object.