JDBFactory.java
SiebelDateBeanPoolManager.java
JDBConnectPooledFactory.java
Siebel JDB 工厂
kateryi@163.com
public class JDBFactory {
public static final Logger log = LoggerFactory.getLogger(JDBFactory.class);
//设置Siebel管理员
public static final void setAuthByAdmin() throws Exception{
UserModel adminUser = new UserModel();
adminUser.setLoginName(PropertiesUtil.getAppContext("siebel.username"));
adminUser.setLoginPwd(PropertiesUtil.getAppContext("siebel.password"));
SystemUtils.setUserModel(adminUser);
}
//获取Siebel数据模型
public static final SiebelDataBean getSiebelDataBean() throws Exception{
//1:检查siebel有没有关闭,关闭的话就获取不到
SystemService service = (SystemService) SpringUtils.getBean("SystemService");//详情见下方
if(service .isOff()){ throw new Exception("Siebel服务暂时关闭");}
//2:siebel服务没有关闭,则从副本中拿。但副本中有可能是空的,也就是说第一次肯定是空的。
SiebelDataBean bean = SystemUtils.getSiebelDataBean(); //在threadLocal中存着的,表示每次获取的都是同一个。
if(bean == null || !isValid(bean)){
if(bean != null ){ //如果不是空的,那么就还回去。为什么不可以接着用?具体方法看下方。
SiebelDataBeanPoolManager.returnObject(bean);
} //如果是空的,也就是第一次,那么就从池子中取一个来用。,并存入副本中。
bean = SiebelDataBeanPoolManager.borrowObject();
SystemUtils.setSiebelDataBean(bean);
}
return bean;
}
//释放Siebel数据模型
public static final void freeSiebelDataBean(){
try{
SiebelDataBean bean = SystemUtils.getSiebelDataBean();
if( bean != null ){
SystemUtils.setSiebelDataBean(null);
SiebelDataBeanPoolManager.returnObject(bean);
}
}catch(Exception e ){
e.printStackTrace();
}
}
//初始化
public static final EAI_Siebel_AdapterBusServAdapter getEAI_Siebel_AdapterBusServAdapter() throws Exception{
EAI_Siebel_AdapterBusServAdapter adapter = new EAI_Siebel_AdapterBusServAdapter(getSiebelDataBean() );
adapter.initialize();
return adapter;
}
//检验
public static boolean isValid(SiebelDataBean sdb) throws Exception{
try{
EAI_Siebel_AdapterBusServAdapter adapter = new EAI_Siebel_AdapterBusServAdapter(sdb);
adapter.initialize();
log.info("Siebel 连接校验成功!");
return true;
}catch(Exception e){
return false;
}
}
}//类尾
SiebelDataBeanPoolManager
public class SiebelDataBeanPoolManager{
public static final Logger log = LoggerFactory.getLogger(SiebelDataBeanPoolManager.class.getName());
pulbic static GenericKeyedObjectPool<String ,PooledSiebelDataBean> pool;
//获取连接池
private static final GenericKeyedObjectPool<String ,PooledSiebelDataBean> getGenericKeyedObjectPool(){
if( pool == null ){
//连接池策略管理
//1:初始化对象池配置
GenericKeyedPoolConfig poolConfig = new GenericKeyedPoolConfig();
poolConfig.setMaxTotal{erKey(20);//对象池中每个key最大实例化对象数
poolConfig.setMaxIdlePerKey(3); //对象池中每个key最大的闲置对象数
poolConfig.setJmxEnable(true);
poolConfig.setJmxNamePrefix("SiebelPoolJmx");
poolConfig.setEvictionPolicyClassName( SiebelPoolEvictionPolicy.class.getName() );
poolConfig.setMinEvictableTimeMillis(PropertiesUtil.getAppContextLong("siebel.pool.minEvictableIdleTimeMillis",500));
poolConfig.setMaxWaitMillis(-1);
//最大连接数,默认100个
poolConfig.setMaxTotal(PropertiesUtil.getAppContextInt("siebel.pool.maxTotal",100));
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);//空闲时候检验
poolConfig.setLifo(false);
//2:初始化对象池
pool = new GenericKeyedObjectPool<String ,PooledSiebelDataBean>(new JDBConnectPooledFactory(),poolConfig);
}
return pool;
}
//取得连接池:用户名|密码 组成
public static String getKey() throws Exception{
String key = String.format("%s|%s",SystemUtils.getUserModel().getLoginName(),SystemUtils.getUserModel().getLoginPwd());
log.info(String.format("key=[%s]",key));
return key;
}
//当连接池满了的时候,处理逻辑
public static final void fullPoolProcess() throws Exception{
//连接池中,连接的数目
GenericKeyedObjectPool<String , PooledSiebelDataBean> pool = getGenericKeyedObjectPool();
int numIdle = pool.getNumIdle();
int numActive = pool.getNumActive();
int num = numActive + numIdle; //空闲+激活
//最大总计
int maxTotal = pool.getMaxTotal();
//连接数已满
if( maxTotal <= num ){
if(numIdle == 0 && maxTotal > 0) throw new ExceptionWithCode("0007");//连接池满
}
try{
//销毁最老的连接
Map<String, List<DefaultPooledObjectInfo>> listMap = pool.listAllObjects();
long firstBorrowTime = -1;
String firstBorrowKey = null;
for(String key : listMap.keySet()){
List<DefaultPooledObjectInfo> list = listMap.get(key);
for(DefaultPooledObjectInfo info : list){
long lastBorrowTime = info.getLastBorrowTime();
if(firstBorrowTime == -1){
firstBorrowTime = lastBorrowTime;
firstBorrowTime = key ;
continue;
}
if(firstBorrowTime > lastBorrowTime){
firstBorrowTime = lastBorrowTime;
firstBorrowTime = key ;
}
}
}
if(firstBorrowKey != null){
PooledSiebelDataBean sdb = pool.borrowObject(firstBorrowKey);
pool.invalidateObject(firstBorrowKey,sdb);
}
}catch(Exception e){
e.printStackTrace();
}//try尾
}//方法尾
//从连接池借取Siebel连接
public static final SiebelDataBean borrowObject() throws Exception{
SiebelDataBean sdb = getGenericKeyedObjectPool().borrowObject(getKey());
log.info("Siebel 连接被借用!");
return sdb;
}
//归还Siebel连接对象到连接池
public static final void returnObject (SiebelDataBean sdb) throws Exception{
getGenericKeyedObjectPool().returnObject( getKey(),(PooledSiebelDataBean) sdb );
log.info("Siebel 连接被归还!");
}
}//类尾
SystemService service = (SystemService) SpringUtils.getBean(“SystemService”);
这一步,说明,是从Spring的上下文中取出该Bean的对象。
具体该Bean 在Spring上下文中有该名字,请看:
包:com.xxxxx.crm.com.service.impl
@Service("SystemService")
public class SystemServiceImpl implements SystemService{
//系统缓存用redisMap,我没用过
public static final Map<String,String > cacheList = new RedisMap<String,String>(SystemServiceImpl.class.getName());
public static final String KEY_SWITCH = "KEY_SWTICH";
public static final String FRONT_JS_CACHE_SWITCH="FRONT_JS_CACHE_SWITCH";
@Override
public void switchControl(boolean off){
if(off){
cacheList.put(KEY_SWITCH,"1");
}else{
cacheList.put(KEY_SWITCH,"0");
}
}
@Override
public boolean isOff(){
return "1".equals( cacheList.get(KEY_SWITCH) );
}
@Override
public void frontJsCacheSwitchCOntrol(boolean off){
if(off){
cacheList.put(FRONT_JS_CACHE_SWITCH,“1”);
}else{
cacheList.put(FRONT_JS_CACHE_SWITCH,“0”);
}
}
@Override
public boolean isFrontJsCacheSwitchOff(){
return "1".equals(cacheList.get(FRONT_JS_CACHE_SWITCH));
}
}
JDBConnectPooledFactory.java Siebel JDB 连接池管理工厂
包:com.xxxxx.crm.thirdparty.siebel.factory
/*
*Siebel JDB 连接池管理工厂
* @Kater Yi -- (kateryi@163.com) --师父邮箱
*/
public class JDBConnectPooledFactory extends BaseKeyedPooledObjectFactory<String ,PooledSiebelDataBean>{
public static final Logger log = LoggerFactory.getLogger( JDBConnectPooledFactory.class.getName() );
//创建连接
@Override
public PooledSiebelDataBean create(String key)throws Exception{
try{
if (StringUtils.isBlank(key)){
throw new ExceptionWithCode("0005"); //用户名,密码没有提供
}
//通过key 取得用户名,密码
String[] keyArray = key.split("\\|"); // 这里只是想用 | ,但是要转义。而且 \| 也是有其他意思的,所以加2个,比如 \t,\b。
if(keyArray.length != 2){
throw new ExceptionWirthCode("0005"); //要么用户名没提供,要么密码没提供 ,或者没有按照固定格式来写。格式: 用户名|密码
}
//当连接池满了的时候,处理逻辑
SiebelDataBeanPoolManager.fullPoolPrcess();
//获取siebel服务
SiebelServer server = SiebelServerManager.getServer();
PooledSiebelDataBean dataBean = new PooledSiebelDataBean(server);
//JDB登录
dataBean.login(server.getUrl(), keyArray[0],keyArray[1],server.getLanguage());
log.info(“Siebel 连接被创建!”);
return dataBean;
}catch(Exception e){
e.printStackTrace();
throw e;
}
}
//这个是 封装连接池对象吗?
@Override
public PooledObject<PooledSiebelDataBean> wrap(PooledSiebelDataBean value){
return new DefaultPooledObject<PooledSiebelDataBean>(value);
}
//销毁对象
@Override
public void destroyObject(String key, PooledObject<PooledSiebelDataBean > p) throws Exception{
super.deatroyObject(key,p);
this.close(key,p);
}
public void close(String key,PooledObject<PooledSiebelDataBean> p){
//登出连接
p.getObject().logoff();
log.info("Siebel 连接被释放!");
}
//验证对象 ----不是很懂
Override
public boolean validateObject(String key,PooledObject<PooledSiebelDataBean> p ){
PooledSiebelDataBean sdb = p.getObject();
try{
//测试连接
if( !JDBFactory.isValid(sdb)){
sdb.getServer().setError(true);
throw new Exception("0006"); //Siebel连接校验失败
}
sdb.getServer().setError(false);
return true;
}catch(Exception e){
sdb.getServer().setError(true);
//标记为 销毁
p.markAbandoned();
try{
//管理连接
this.close(key,p);
}catch(Exception ee){
ee.printStackTrace();
}
return false;
}
}
}//类尾