All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alogic.rpc.facade.FacadeFactoryImpl Maven / Gradle / Ivy
package com.alogic.rpc.facade;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alogic.rpc.Call;
import com.alogic.rpc.CallException;
import com.alogic.rpc.naming.CallFactory;
import com.anysoft.util.Properties;
import com.anysoft.util.Settings;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.LoaderClassPath;
import javassist.Modifier;
import javassist.NotFoundException;
/**
* 通过Call实现的FacadeFactory
*
* @author duanyy
* @since 1.6.7.15
*
* @version 1.6.8.8 [20170417 duanyy]
* - 对象缓存改为基于callId+className缓存
*/
public class FacadeFactoryImpl extends FacadeFactory.Abstract{
/**
* a logger of log4j
*/
protected static final Logger LOG = LoggerFactory.getLogger(FacadeFactory.class);
/**
* 缓存已经找到的类
*/
private static Map> cachedClass = new ConcurrentHashMap>();
/**
* 缓存已经创建的类
*/
private Map cachedObject = new ConcurrentHashMap();
public FacadeFactoryImpl(){
// nothing to do
}
@Override
public I getInterface(String callId, Class clazz) {
return getInterface(callId,"",clazz);
}
@SuppressWarnings("unchecked")
@Override
public I getInterface(String callId, String service, Class clazz) {
try {
String className = clazz.getName() + "Facade" + service;
Facade facade = cachedObject.get(className + callId);
if (facade == null){
synchronized(this){
facade = cachedObject.get(className);
if (facade == null){
Call call = CallFactory.getCall(callId);
if (call == null){
throw new CallException("core.e1003","Can not find a call named " + callId);
}
Class facadeClass = makeFacadeClass(StringUtils.isEmpty(service)?clazz.getName():service,className,clazz);
facade = (Facade) facadeClass.getDeclaredConstructor().newInstance();
facade.setCall(call);
cachedObject.put(className + callId, facade);
}
}
}
return (I)facade;
} catch (NotFoundException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (CannotCompileException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (IOException e) {
throw new CallException("core.e1004",e.getMessage(),e);
} catch (InstantiationException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (IllegalAccessException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (ClassNotFoundException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (NoSuchMethodException e) {
throw new CallException("core.e1002",e.getMessage(),e);
} catch (InvocationTargetException e) {
throw new CallException("core.e1002",e.getMessage(),e);
}
}
@Override
public void configure(Properties p) {
// nothing to do
}
@SuppressWarnings("unchecked")
private static Class makeFacadeClass(String service,String className,Class intf) throws NotFoundException, CannotCompileException, IOException, ClassNotFoundException{
@SuppressWarnings("rawtypes")
Class clazz = cachedClass.get(className);
if (clazz == null){
synchronized (FacadeFactoryImpl.class){
ClassPool pool = ClassPool.getDefault();
pool.appendClassPath(new LoaderClassPath(Settings.getClassLoader()));
CtClass cc = getClassIfExist(pool,className);
if (cc == null){
LOG.debug("Generate facade class...");
LOG.debug("Class:" + className);
CtClass facadeBase = pool.get(Facade.class.getName());
LOG.debug("Base class:" + facadeBase.getName());
cc = pool.makeClass(className,facadeBase);
CtClass intfClass = pool.get(intf.getName());
cc.setInterfaces(new CtClass[]{intfClass});
LOG.debug("Interface class:" + intfClass.getName());
CtMethod [] methods = intfClass.getMethods();
for (CtMethod m:methods){
if ((m.getModifiers() & Modifier.ABSTRACT) != 0) {
//只去实现abstract方法
CtMethod ctMethod = CtNewMethod.make(
m.getModifiers() ^ Modifier.ABSTRACT,
m.getReturnType(),
m.getName(),
m.getParameterTypes(),
m.getExceptionTypes(), "{return ($r) execute(\"" + service + "\",\"" + m.getName() + "\",$args);}",
cc);
cc.addMethod(ctMethod);
LOG.debug("Add method:" + ctMethod.getLongName());
}
}
LOG.debug("Facade class is generated successfully.");
clazz = cc.toClass();
}else{
clazz = Settings.getClassLoader().loadClass(className);
}
cachedClass.put(className, clazz);
}
}
return clazz;
}
private static CtClass getClassIfExist(ClassPool pool,String name){
return pool.getOrNull(name);
}
}