Due to system architecture changes, agent technology needs to be used. Studied the Java commonly used 3 kinds of proxy way, here does the summary which uses. The following is a brief introduction to JDK, Cglib, Javaassit, respectively. The ASM is missing here because ASM is more complex to use and has very few scenes to use. JDK
The advantage of using JDK Proxy is that it is Java-self-contained and no longer relies on any third-party jar packages. The downside is that it can only act as an agent for the interface.
Class Injectproxy implements Invocationhandler {
private Object target;
Private Injectproxy (Object target) {
this.target = target;
}
public object invoke (object proxy, Method method, object[] args) throws throwable{return
Method.invoke (target, args) ;
}
}
Invocationhandler ih = new Injectproxy (target);
ClassLoader ClassLoader = InjectProxy.class.getClassLoader ();
Return Proxy.newproxyinstance (ClassLoader, Target.getclass (). Getinterfaces (), IH);
Cglib
Cglib is familiar, it encapsulates the ASM complex interface and is simpler to use.
Cglib consists of 4 concepts, beangenerator, enhancer, Methodinterceptor, Lazyloader, and Dispatcher. Beangenerator
Beangenerator is mainly used to dynamically generate a subclass of a class, you can dynamically add some member variables to the subclass, automatically generate getter, setter method. The disadvantage is that it can only generate subclasses that contain default constructors.
Beangenerator Gen = Beangenerator ();
Gen.setsuperclass (superclass.class);
Gen.addproperty ("name", String.class);
Class Subclazz = (Class) Gen.createclass ();
Superclass obj = (superclass) gen.create ();
Enhancer
Enhancer an AOP feature used to implement a method invocation. Enhancer generated objects will contain many properties that are automatically added to the Cglib, so the resulting object will be relatively large. Methodinterceptor
public class Methodinterceptorimpl implements methodinterceptor{
@Override the Public
object intercept (Object obj , method method, object[] args, Methodproxy proxy) throws Throwable {return
proxy.invokesuper (obj, args);
}
//proxy Invoke method
Enhancer enhancer = new enhancer ();
Enhancer.setsuperclass (clazz);
Enhancer.setcallbacks (New callback[]{noop.instance, New Methodinterceptorimpl ());
Enhancer.setcallbackfilter (New Callbackfilter () {
@Override public
int Accept (method method) {
// Intercepts only the Invoke method of the algorithm interface definition
if (method.getname (). Equals ("Invoke")) return
1;
return 0;
}
});
Enhancer.setusefactory (false);
New Objects Object
proxy = Enhancer.create ();
Lazyloader
Lazyloader is the CGLIB proxy delay initialization interface. When an interface method is called for the first time, the object actually to be accessed is determined. What do you mean. Look at the code
public class Concreteclasslazyloader implements lazyloader{public class Propertybean {private String proper
Tyname;
Public String Getpropertyname () {return propertyname;
} public void Setpropertyname (String propertyname) {this.propertyname = propertyname; @Override public Object Loadobject () throws Exception {System.out.println ("Lazyloader loadobje
CT () ... ");
Propertybean bean=new Propertybean ();
Bean.setpropertyname ("Lazy-load object propertyname!");
return bean;
public static void Main (string[] args) {enhancer enhancer=new enhancer ();
Enhancer.setsuperclass (Propertybean.class);
Propertybean Propertybean = (Propertybean) enhancer.create (propertybean.class,new concreteclasslazyloader ());
The Loadobject System.out.println (Propertybean.getpropertyname ()) is recalled here; System.out.println ("After ...");
After the LOADOBEJCT is no longer callback, direct access to the object System.out.println (Propertybean.getpropertyname ()) is returned for the first time. }
}
Dispatcher
The dispatcher function is the same as Lazyloader, except that dispatcher is recalled every time.
public class Concretedispatcher implements dispatcher{public class Propertybean {private String Propertynam
E
Public String Getpropertyname () {return propertyname;
} public void Setpropertyname (String propertyname) {this.propertyname = propertyname; @Override public Object Loadobject () throws Exception {System.out.println ("Dispatcher loadobje
CT () ... ");
Propertybean bean=new Propertybean ();
Bean.setpropertyname ("Dispatcher object propertyname!");
return bean;
public static void Main (string[] args) {enhancer enhancer=new enhancer ();
Enhancer.setsuperclass (Propertybean.class);
Propertybean Propertybean = (Propertybean) enhancer.create (propertybean.class,new concretedispatcher ());
The Loadobject System.out.println (Propertybean.getpropertyname ()) is recalled here;
System.out.println ("After ...");Each time callback Loadobejct System.out.println (Propertybean.getpropertyname ()); }
}
Cglib Summary
Beangenerator suitable for subclass plus member variables
Methodinterceptor is a good way to intercept.
Lazyloader and dispatcher are suitable for object routing javaassist
Javaassist use less than cglib, because it is more difficult to use than cglib, can be dynamically splicing source to generate objects is its strengths. Generating Subclasses
Protected Ctclass Createsubclass (class<?> clazz) throws Cannotcompileexception, Notfoundexception,
classnotfoundexception{/*javassist generates subclasses with Needlog attributes */classpool pool = Classpool.getdefault ();
String proxyclassname = clazz.getname () + "$LogAble";
Ctclass cc = Pool.getornull (proxyclassname);
if (cc = null) {cc = Pool.makeclass (proxyclassname);
Cc.setmodifiers (Modifier.public);
Parent class Ctclass superclass = Pool.getornull (Clazz.getname ());
if (superclass = = null) superclass = Pool.makeclass (Clazz.getname ());
Cc.setsuperclass (superclass);
Constructor Ctclass Stringclass = Pool.get ("java.lang.String");
ctclass[] Constructorparamclassarr = new Ctclass[]{stringclass}; Generate a half-class constructor Ctconstructor CTC = Ctnewconstructor.make (Constructorparamclassarr,null,ctnewconstructor.pass_param
S,null,null, CC);
Cc.addconstructor (CTC); Interface AddInterface (CC, LogaoPfilter.class);
Add Needlog Properties Addclassproperty (cc, "Needlog", Boolean.class);
/*javassist Method End */return CC; * * * Subclass ADD Interface * * protected void AddInterface (Ctclass cc, class<?> interfaceclass) {Classpool pool = Classpool
. Getdefault ();
Ctclass ccinterface = Pool.getornull (Interfaceclass.getname ());
if (Ccinterface = = null) Ccinterface = Pool.makeinterface (Interfaceclass.getname ());
Cc.addinterface (Ccinterface); * * * Subclass Add Properties */protected void Addclassproperty (Ctclass cc, String name, class<?> type) throws Cannotcompileexce
ption{Addclassproperty (CC, Name, type, "");} protected void Addclassproperty (Ctclass cc, string name, class<?> type, string decorate) throws Cannotcompileexcept
ion{Ctfield field = Ctfield.make (String.Format ("private%s%s%s;", Decorate, Type.getname (), name), CC);
Cc.addfield (field); Ctmethod GetMethod = Ctmethod.make (String.Format ("Public%s get%s () {return%s;}", Type.getname(), name.substring (0, 1). toUpperCase () + name.substring (1), name), CC);
Cc.addmethod (GetMethod); Ctmethod Setmethod = Ctmethod.make (String.Format ("public void set%s (%s value) {this.%s = $1;return;}", Name.substring (0,
1). toUpperCase () + name.substring (1), Type.getname (), name), CC);
Cc.addmethod (Setmethod); }
build Agent
Javaassit the process of generating proxy objects is similar to Cglib.
Private class Methodhandlerimpl implements Methodhandler {
final Object delegate;
Methodhandlerimpl (Object delegate) {
this.delegate = delegate;
}
Public Object invoke (Object Self, Method M, method proceed, object[] args) throws Throwable {return
M.invoke (delegate , args);
}
Proxyfactory proxyfactory = new Proxyfactory ();
Proxyfactory.setsuperclass (superclass.class);
Proxyfactory.setinterfaces (new class[] {superinterface.class});
class<?> Proxyclass = Proxyfactory.createclass ();
Superinterface proxy = (superinterface) proxyclass.newinstance ();
((proxyobject) proxy). SetHandler (New Methodhandlerimpl (delegate));
Performance Comparison
There are a lot of performance tests for proxy objects generated by three frameworks, which can be referenced in this article.
Basically the order is
Javaassit stitching source Generation method (5 times times) > Cglib Methodinterceptor generated method (twice times) > JDK proxy generation > Javaassist metho Dinterceptor the generated method.