본문 바로가기

Java

Jrebel Ibatis plugin.

보니까.. Jrebel 에서 플러그인 제공하는 방식이
프레임워크에 소스를 끼워넣어서
인터셉트 혹은 특정 메서드 실행 후에 동작 할 수 있도록
해주는 방식이 있어서...

아주 심플하게 생각해서...
sqlmapclient를 사용하기 위해
SqlMapClientBuilder를 사용해서

SqlMapClient client = SqlMapClientBuilder.buildSqlMapClient(reader);
를 실행 할 때마다 reader를 체크하여 reload해주면 되지 않을까 생각...

그냥 쓸 때마다 xml을 읽어오도록 구성 되어 있으면 문제 없지만 보통은 최초 기동시에 xml 정보를 읽어 놓고
그것을 재사용 하는 방법을 사용하고 있을 것이므로... 재기동이 문제가 되는 경우가 있다.

일단 , 최종 수정일을 체크해야겠지만
동작되는지 보는게 급해서..그냥 만들어 보았다.

//IbatisPlugin.java
package org.zeroturnaround.javarebel.integration.ibatis;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zeroturnaround.javarebel.ClassResourceSource;
import org.zeroturnaround.javarebel.IntegrationFactory;
import org.zeroturnaround.javarebel.Plugin;
import org.zerturnaround.javarebel.integration.ibatis.cbp.SqlMapClientBuilderCBP;
public class IbatisPlugin implements Plugin {
ClassLoader cl = IbatisPlugin.class.getClassLoader();
@Override
public boolean checkDependencies(ClassLoader arg0, ClassResourceSource arg1) {
return true;
}
@Override
public String getAuthor() {
return "need4spd";
}
/* (non-Javadoc)
* @see org.zeroturnaround.javarebel.Plugin#getDescription()
*/
@Override
public String getDescription() {
return "ibatis plugin";
}
/* (non-Javadoc)
* @see org.zeroturnaround.javarebel.Plugin#getId()
*/
@Override
public String getId() {
return "";
}
/* (non-Javadoc)
* @see org.zeroturnaround.javarebel.Plugin#getName()
*/
@Override
public String getName() {
return "need4spd";
}
/* (non-Javadoc)
* @see org.zeroturnaround.javarebel.Plugin#getWebsite()
*/
@Override
public String getWebsite() {
return "devyongsik.tistory.com";
}
/* (non-Javadoc)
* @see org.zeroturnaround.javarebel.Plugin#preinit()
*/
@Override
public void preinit() {
IntegrationFactory.getInstance()
.addIntegrationProcessor(
cl,
"com.ibatis.sqlmap.client.SqlMapClientBuilder",
new SqlMapClientBuilderCBP());
}
}
view raw 1.java hosted with ❤ by GitHub


//SqlMapClientBuilderCBP.java
package org.zerturnaround.javarebel.integration.ibatis.cbp;
import org.zeroturnaround.bundled.javassist.ClassPool;
import org.zeroturnaround.bundled.javassist.CtClass;
import org.zeroturnaround.bundled.javassist.CtMethod;
import org.zeroturnaround.javarebel.integration.support.JavassistClassBytecodeProcessor;
public class SqlMapClientBuilderCBP extends JavassistClassBytecodeProcessor{
public void process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception {
System.out.println(ctClass.getName());
CtMethod m = ctClass.getMethod("buildSqlMapClient","(Ljava/io/Reader;)Lcom/ibatis/sqlmap/client/SqlMapClient;");
m.insertBefore("org.zeroturnaround.javarebel.integration.ibatis.DaoXmlManager" +
".test($1);");
}
}
view raw 2.java hosted with ❤ by GitHub


//DaoXmlManager.java
package org.zeroturnaround.javarebel.integration.ibatis;
import java.io.IOException;
import java.io.Reader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ibatis.common.resources.Resources;
import com.skt.omp.common.db.SqlMapLoader;
public class DaoXmlManager {
private Log logger = LogFactory.getLog(DaoXmlManager.class);
public static void test(Reader reader) {
try {
//이쯤에서 xml파일의 변경을 체크하거나 하면 좋을 듯...
reader = Resources.getResourceAsReader("SqlMapConfig.xml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
view raw 3.java hosted with ❤ by GitHub

위 소스는 SqlMapClientBuilder.buildSqlMapClient(Reader reader) 가 호출 될 때마다
그전에 reader를 다시 읽어들이는 방식이라 굉장히 비효율적이다.
아니 비효율 정도가 아니라..SqlMapConfig.xml이 커지면..매번 저걸 호출하게 되므로
개발하기가 쉽지 않다 -.-;

반드시 파일 변경 여부를 체크하는 로직이 들어가야 할 듯....

어차피 사이트마다 SqlMapClient를 호출하는 부분이 다르기 때문에
어디에서 인터셉트를 해야 할지 천차만별이라...
아무튼...

Manager 클래스에서 적당히 xml을 체크해서 변경된 녀석이 있으면 reader를 다시 읽도록 하던가...
아니면..Ibatis를 더 까고 들어가서 (사실 IbatisPlugin이라고 하면 이게 맞을 듯...)
어딘가 Map 같은 걸로 관리 되고 있을 각각의 쿼리 XML 파일만 다시 load되도록 해주면
좀 더 멋진 코드가 작성 될 수 있을 것 같다.

라고 하지만..아이바티스..2.3 버전은
JavassistClassBytecodeProcessor 의 제약에 너무 많이 걸린다..


암튼..일단, 플러그인 작동 방식이 궁금해서 작성해본 것... 우리 사이트에 맞게 수정해서 만들었는데
꽤 잘 된다...
JavassistClassBytecodeProcessor를 알게 된 것도.. 큰 행운..


저런 생각을 하는 사람들은
정말 뭐하는 사람들일까.. --; AOP 비슷하기도 하고... 대단하다..