Java defines its own proxy under the java.lang.reflect package. Using the classes in this package, we can dynamically create a proxy class and implement one or more interfaces at runtime. And forwards the method call to the specified class. Because the actual proxy is created at runtime, it is called a dynamic proxy.
Proxy: It is completely generated by java and implements a complete subject interface.
InvocationHandler:Proxy method calls on proxy will be passed into this class, and Invocation Handler controls access to RealSubject.
Because Java has helped us create the proxy class, we need a way to tell the proxy class what you want to do. We can't write the code into the proxy class as before because we didn't implement the proxy class. So where should we put it? Put it in the InvocationHandler class, which responds to any call by the proxy. We can think of InvocationHandler as the object that the agent requests to do the actual work after receiving the method call.
2.Java . lang . reflect . invocation handler
There is only one invoke () method in an interface implemented by the proxy instance, and its signature is as follows;
Java code
Common object call (object proxy, method method, object [] parameter)
When the proxy method is called, the proxy forwards the call to InvocationHandler and calls its invoke () method.
3.java.lang.reflect Agent
Provides static methods for creating dynamic proxy classes and instances, which are also superclasses of all dynamic proxy classes created by these methods. The static methods we often use are:
Java code
NewProxyInstance(ClassLoader, Class[] interface, InvocationHandler h)
4. Example:
Situation: You can view and modify the name and gender, but you cannot modify the rate. Others can view the name, gender and modify the rate, but they cannot modify the name and gender.
4. 1 defines an interface:
Java code
Public interface personnel {
string getName();
string getGender();
Void setName (string name);
Void setGender (string gender);
void setRate(int rate);
int getRate();
}
4.2 define the class that implements the Person interface
Java code
The public class PersonImpl implements Person {
String name;
String gender;
String interest;
Interest rate;
Public string getName() {
Returns the name;
}
Public void setName {
this.name = name
}
Public string getGender() {
Return to gender;
}
public void set gender(String gender){
This.gender = gender;
}
Common string getInterests() {
Return interest;
}
public void set interests(String interests){
This.interests = interests;
}
public int getRate() {
Rate of return;
}
Public void set rate (int rate) (
this.rate = rate
} [Next Page]
4.3 define the OwnerInvocationHandler class, which means that if you are yourself, you can modify it to check the gender of your name.
Java code
The public class OwnerInvocationHandler implements InvocationHandler{
Private personBean
public OwnerInvocationHandler(Person Person bean){
this . person bean = person bean;
}
@ Overlay
Common object call (object proxy, method method, object [] parameter)
Raise IllegalAccessException {
Try {
If (method. getname()。 Starts with(" get "){// If the method name is get, the corresponding method of get in the person class is called.
Returns method.invoke(personBean, args);
} else if (method. getname()。 Equals(" setRate "){// If the method is set rate, an exception will be thrown.
Throw a new IllegalAccessException ("Access Denied");
} else if (method. getname()。 Starts with(" set "){// If set, call the corresponding method of set in the person class.
Returns method.invoke(personBean, args);
} Otherwise {
System.out.println ("non-method call");
}
} catch(InvocationTargetException e){
e . printstacktrace();
}
Returns null
}
}
4.4 define the non-invocationHandler class, that is to say, if it is not yourself, you can check the name and gender and modify the rate.
Java code
The public class nonvocationhandler implements InvocationHandler{
//
#p# Subtitle #e#
Private individuals;
Public non-professional processor (person person) (
This.person = person;
}
@ Overlay
Common object call (object proxy, method method, object [] parameter)
Throwable
if(method.getName()。 startsWith("setRate")){
Returns method.invoke(person, args);
}else if (method.getName()。 starts with(" get "){
Returns method.invoke(person, args);
} Otherwise {
System.out.println ("non-method call");
Returns null
}
}
}
4.5 test class MyDynamicProxy
Java code
Public class MyDynamicProxy {
Public person getownerpersonbeanproxy (person person) {
return(Person)proxy . newproxyinstance(Person . getclass()。 getClassLoader(),
person.getClass()。 getInterfaces(),new OwnerInvocationHandler(person));
}
public Person getnonpersonbean proxy(Person Person){
return(Person)proxy . newproxyinstance(Person . getclass()。 getClassLoader(),
person.getClass()。 getInterfaces(),new nonvocationhandler(person));
}
Public static void main(String[] args) {
MyDynamicProxy MDP = new MyDynamicProxy();
MDP . test();
}
Public Invalid Test () {
//
person person = getpersonbean fromdb 1();
person person proxy = getOwnerPersonBeanProxy(person);
system . out . println(person proxy . getname());
Try {
person proxy . set rate(2);
Catch (exception e) {
System.out.println ("rate cannot be set");
}
//
person person 1 = getpersonbean fromdb 1();
person person proxy 2 = getNonPersonBeanProxy(person 1);
system . out . println(person proxy 2 . getname());
person proxy 2 . set rate(2);
system . out . println(person proxy 2 . getrate());
}
Private getPersonBeanFromDB 1(){
person Pb = new person impl();
Pb . set name(" remy ");
Pb . set gender(" girl ");
Pb . set rate( 1);
Return Pb; }
Output result:
Java code
Remy can't set Remy 2.
#p# Subtitle #e#