Customize a scene, play the computer and sleep, the computer can only be people play, but people, cats, dogs can sleep
here will play games and sleep abstract two methods:
1.playComputer
2.sleep
to abstract humans and animals into a class:
1.Animal
But how to add the custom annotation through the dynamic proxy to let the Playcomputer only lets the human call, the Sleep method person, the cat, the dog all can call?
One idea is to annotate the method, and the annotation's content is to allow access to the animal type of the method, to intercept the Playcomputer or sleep method when called. and the annotation value above the invoked method is compared to the type of the calling object animal, which is accessed if it is included, and is not invoked if it is not included.
Note: The dynamic proxy for JDK is used here, so need to put the annotation on the interface, if put to the target class method above will lead to read, if the use of Cglib dynamic agent, of course, it does not need interface, directly to the target class method can also read the contents of the annotation.
The following works:
first customize the annotation and define the human, cat, and dog constants inside:
@Target (Elementtype.method)
@Retention (retentionpolicy.runtime) public
@interface Secure {
string[] Values ();
static String HUMAN = "HUMAN";
static String DOG = "DOG";
static String CAT = "Cat";
}
to abstract people, cats, dogs into animal classes:
public class Animal {
private String name;
Private String type;
Getter and setter ...
Public String toString () ...
Interface class:
Public interface Deal {
@Secure (values = {Secure.human}) public
String Playcomputer (Animal a);
@Secure (values = {Secure.human, secure.cat, Secure.dog}) public
String sleep (Animal a);
}
Target class:
public class Dealimpl implements Deal {public
string Playcomputer (Animal a) {
string re = A + "Playcomputer, D Ealimpl method ";
System.out.println (re);
return re;
}
Public String Sleep (Animal a) {
string re = A + ' sleep, Dealimpl method ';
System.out.println (re);
return re;
}
}
a key proxy class in which the annotation contents of the invoked method are taken out, and the caller's type is matched:
public class Proxydeal implements Invocationhandler {private Object target;
public object bind (Object target) {this.target = target; Object targetproxy = proxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). GetInterfaces (),
this);
return targetproxy;
public object invoke (object proxy, Method method, object[] args) throws Throwable {Animal = null;
Object result = null;
if (null!= args && args.length!= 0) {animal = (animal) args[0]; } if (Method.isannotationpresent (Secure.class)) {Secure annotation = method.getannotation (secure.clas
s);
String[] values = Annotation.values (); if (null!= values && values.length!= 0) {for (String value:values) {if (
Value.trim (). Equals (Animal.gettype (). Trim ()) {result = Method.invoke (target, args); return result;
} System.out.println ("No access:" + animal);
return null;
} annotation.values ();
return result; }
}
To test the main function:
public class Securemain {public
static void Main (string[] args) {
Deal Deal = new Dealimpl ();
Proxydeal proxy = new Proxydeal ();
Deal dealproxy = (Deal) proxy.bind (Deal);
Animal Animal = new Animal ("Zhangsan", secure.cat);
String Re1 = dealproxy.playcomputer (animal);
String Re2 = dealproxy.sleep (animal);
System.out.println (Re1 + " main");
System.out.println (Re2 + " main");
}
Test Results: