JavassistProxyFactory: uses bytecode technology to create objects
public <T> T getProxy(Invoker<T> invoker,Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(newInvokerInvocationHndler(invoker));
}
It seems to be the same as the jdk generation proxy. In fact, the Proxy class here is not the com.alibaba.dubbo.common.bytecode.Proxy that comes with the jdk to generate the proxy object.
The Proxy class written by Dubbo himself uses the interface to be proxyed to generate proxy code using the javassist tool.
Get the Invoker object
public <T> Invoker<T> getInvoker(T proxy,Class<T> type, URL url) {
final Wrapper wrapper =Wrapper.getWrapper(proxy.getClass().getName().inde xOf('$') < 0 ?proxy.getClass() : type);
returnnew AbstractProxyInvoker<T>(proxy, type, url) {
protected Object doInvoke(T proxy,String methodName,
Class<?>[] parameterTypes,Object[] arguments)throwsThrowable {
returnwrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
Create a wrapper object Wrapper based on the class information of the incoming proxy object
Returns an instance of the Invoker object. The invoke method of the invoker object can call the proxy object according to the method name and method parameters contained in the incoming invocation object and return the result of the call
com.alibaba.dubbo.common.bytecode.Proxy Tool class for generating proxy objects
1. Traverse all the input parameter interfaces, split and connect them, use it as the key and map as the cache to find if there is any, it means that the proxy object has been created and returned
2. Use the AtomicLong object to auto-increment to obtain a long array as the suffix of the production class to prevent conflicts
3. Traverse the interface to get all the defined methods, and add them to a collection Set<String> worked to judge the weight,
Get the index subscript ix of the method y should be in the methods array
Get the parameter type and return type of the method
Construct the method body return ret= handler.invoke(this, methods[ix], args); The method call here is actually delegated to the InvokerInvocationHandler instance object, to call the real instance method and add it to the methods array
4. Create a proxy instance object ProxyInstance
The class name is pkg + ".poxy" + id = package name + ".poxy" + self-incrementing value
Add static field Method[] methods;
Add instance object InvokerInvocationHandler hanler
Add the constructor parameter is InvokerInvocationHandler
Add no-argument constructor
Use the tool class ClassGenerator to generate the corresponding bytecode
5. Create a proxy object, and its newInstance(handler) method is used to create a proxy based on our interface
// create Proxy class.
String fcn = Proxy.class.getName() + id;
ccm = ClassGenerator.newInstance(cl);
ccm.setClassName(fcn);
ccm.addDefaultConstructor();
ccm.setSuperClass(Proxy.class);
ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
Class<?> pc = ccm.toClass();
proxy = (Proxy)pc.newInstance();
Proxy object name Proxy + id
Inherited from Proxy, so implement the newInstance method
Add default constructor
Implementation method newInstance code, new pcn(hadler) where pcn is the class name of the proxy object generated earlier
Use the tool class ClassGenerator to generate bytecode and instantiate the object to return