À̹ø ¾ÆƼŬ¿¡¼´Â Ŭ·¡½ºÆнº¿¡ Æ÷ÇԵǾîÀÖÁö ¾ÊÀº Ŭ·¡½º¿¡ ´ëÇÑ µ¿Àûº¯°æ½Ã ¾ÖÇø®ÄÉÀ̼ÇÀÇ
Àç±âµ¿¾øÀÌ Å¬·¡½º¸¦ ·ÎµùÇÏ´Â ¹æ¹ýÀ» º¸°íÀÚ ÇÑ´Ù.
¿¹Àü¿¡ ÀÌ·¯ÇÑ °ÍÀ» ¾ÆƼŬ·Î ¾²°Ú´Ù°í °ø¾ðÇßÀ¸³ª, ±Ý¹æ ÁöÅ°Áö ¸øÇÑ°É ÈÄȸÇÏ°í ÀÖ´Ù.
¿Ö³Ä~ ³î»õ~°¡ ³Ê¹«³ªµµ ¹Ù»Ñ±â ¶§¹®¿¡.. ¹Ù»Û°Ô ÁÁ±ä ÇÏÁö¸¸ ³Ê¹« ¹Ùºüµµ Á×À» °Í °°´Ù.
°Ô´Ù°¡ Æȸñ±îÁö ºÎ·¯Áø(5¿ù1ÀÏ ³ëµ¿Àý ±â³äÀ¸·Î ºÎ·¯Áü) ¸¶´ç¿¡ ¼Õ±îÁö Á¦´ë·Î ¾µ¼ö ¾ø´ø ¸¶´ç¿¡
ÀϱîÁö ¸¹ÀÌ °ãÃĹö¸®´Ï ¿ø~
¢º Dynamic Class Loading Technique
À̹ø¿¡ ¿©·¯ºÐµé¿¡°Ô º¸ÀÏ ¿¹Á¦¿¡¼´Â ¾ÖÇø®ÄÉÀ̼ÇÀÇ Àç½ÃÀÛ¾øÀÌ µ¿ÀûÀ¸·Î º¯°æµÈ Ŭ·¡½ºÆÄÀÏÀ»
¾Ë¾Æä¾î Ŭ·¡½º·Î´õ¿¡ µî·Ï½ÃÄÑ »ç¿ëÇÒ ¼ö ÀÖ´Â deployÀü·«À» ¼¼¿öº¸µµ·Ï ÇÑ´Ù.
½Ã°£ÀÌ ÀÖÀ¸¸é ±¸Ã¼ÀûÀÎ °ÍÀ» ÀÌ¿ëÇÏ¿© ½ÇÁ¦ »ç¿ëµÉ ¼ö ÀÖ´Â °ÍÀ» º¸ÀÌ°ÚÁö¸¸ Ç×»ó ±×·¨µíÀÌ
¿ì¼± ¸Àº¸±â·Î ±âº»ÀûÀÎ ±âÃʸ¦ ´ÙÁöµµ·Ï ÇÏÀÚ.
¿©±â¼ Àû¿ëµÇ´Â °ÍÀº ºÐ¸®µÈ Ŭ·¡½º ·Î´õ¸¦ ÀÌ¿ëÇÏ¿© daemon °ú´Â °ü°è¾øÀÌ ¿ì¸®ÀÇ ¾ÖÇø®ÄÉÀ̼ǿ¡¸¸
Àû¿ëÀÌ µÇµµ·Ï ÇÏ°Ô ÇØ¾ß ÇÒ °ÍÀÌ´Ù.
ÀÚ. ÀÌ ±ÛÀ» Àд ´ç½Å ¸ÕÀú »ý°¢ºÎÅÍ Çغ¸¶ó~
¾î¶»°Ô Çϸé Ŭ·¡½º°¡ º¯°æµÇ¾ú´Ù´Â °ÍÀ» ¾Ë¾ÆÂ÷¸®°Ô ÇÒ °ÍÀΰ¡?
½º·¹µå·Î ¹«ÇÑ ·çÇÁ Çϳª µ¹¸®¸é¼ ¹«Á¶°Ç Ŭ·¡½º·Ñ reloadÇÏ°Ô ÇÒ°ÍÀΰ¡? ¾Æ´Ï¸é Ŭ·¡½º°¡
º¯°æµÇ¾úÀ» ¶§¸¸ ·ÎµùÇÏ°Ô ÇÒ°ÍÀΰ¡?
Àá½Ã µý À̾߱âÁö¸¸
¸ÅÆ®¸¯½º2¿¡¼ ¿À¶óŬÀº "¼±ÅÃÀº ÀÌ¹Ì µÇ¾ú´Ù. ¹®Á¦´Â ´ç½ÅÀÌ ±×°ÍÀ» ÀÌÇØÇØ¾ß Çϴ°ÍÀÌ´Ù~"¶ó°í
À̾߱âÇÑ´Ù. À§¿¡¼ Áú¹®À» ÇÑ°Íó·³ °áÁ¤Àº ÀÌ¹Ì µÈ »óȲÀ̸ç, ³î»õ~´Â ±×°ÍÀ» ¾î¶»°Ô ¿©·¯ºÐ¿¡°Ô
ÀÌÇظ¦ ½ÃÄÑ¾ß Çϸç, ¿©·¯ºÐµéÀº ¾î¶»°Ô ÀÌÇØÇÒ°ÍÀÎÁöÀÇ ¹®Á¦ÀÎÁöµµ ¸ð¸£°Ú´Ù.
ÀÌ¹Ì ¼±ÅÃÀº ÇßÀ» °ÍÀ̸®¶ó º»´Ù. ÈÄÀÚÂÊÀÌ ´õ °¡±î¿ïµí Çѵ¥ ¸¸¾à¿¡ ÈÄÀÚ¸¦ ¼±ÅÃÇß´Ù¸é
±× ¹æ¹ýÀº? ´ç±Ù API¿¡ ³ª¿ÍÀÖÀ¸¸®¶ó~
¿©±â¼ Áß¿äÇÑ°ÍÀº Ŭ·¡½º°¡ º¯°æµÇ¾î »õ·Î¿î Ŭ·¡½º·Î´õ¸¦ »ç¿ëÇßÀ» ¶§´Â ±âÁ¸ÀÇ Å¬·¡½º·Î´õ¸¦ ºÒÇÊ¿äÇÏ°Ô
³²°ÜµÎÁö ¸»°í ¾ø¾Ö¹ö·Á¾ß ÇÔÀº ¹°·ÐÀÌ´Ù.
¶ÇÇÑ ÀÌ·¯ÇÑ Á¤º¸µéÀÌ ¸í½ÃÀûÀΠŬ·¡½ºÆнº¿¡ Ãß°¡°¡ µÇ¾îÀÖÁö ¾ÊÀ½À» ¾Ë¾Æ¾ß ÇÒ °ÍÀÌ´Ù.
¿ì¼± º¯°æ´ë»óÀÌ µÇ´Â Ŭ·¡½º¸¦ ¸ÕÀú ÀÛ¼ºÇغ¸µµ·Ï ÇÏÀÚ.
¢º ReloadTargetClass.java
package carouser;
public class ReloadTargetClass{
public String hiCarouser(){
return "±âÃÊ¿¡ Ãæ½ÇÇÏÀÚ";
}
}
|
À§¿Í °°Àº Ŭ·¡½º°¡ ÀÛ¼ºµÇ¾ú´Ù°í ÇßÀ» ¶§ ÀÏ¹Ý java.io.File API¸¦ ÅëÇÏ¿© À§ ÆÄÀÏÀÌ º¯°æµÈ°ÍÀ»
¾Ë¾ÆÂ÷¸®°Ô ÇÑ´Ù¸é ¾î¶»°Ô Äڵ尡 ÀÛ¼ºÀÌ µÇ¾î¾ß ÇÒ°ÍÀΰ¡?
lastModified()?
Èì.. À§ÀÇ API¸¦ ¾²°Ô µÇ¸é ÆÄÀÏÀÇ ÃÖÁ¾ º¯°æ½Ã°£À» ¾Ë ¼ö ÀÖÀ» °ÍÀ̹ǷÎ, ÇØ´ç ¸Þ¼Òµå¸¦ ÀÌ¿ëÇÏ¿©
ÆÄÀÏÀÌ º¯°æµÇ°Ô ÇÏ´Â °ÍÀ» ¾Ë¸é µÉ°ÍÀÌ´Ù.
¾î¶°ÇÑ °ÍµéÀÌ ÇÊ¿äÇÒ °ÍÀÎÁö ºÐ¼®À» Çغ¸µµ·Ï ÇÏÀÚ. ½Ã³ª¸®¿À¸¦ Â¥ÀÚ´Â °ÍÀÌ´Ù.
³î»õ~°¡ »ý°¢ÇÏ´Â °Í°ú ºñ½ÁÇÏ°Ô ¿©·¯ºÐµµ »ý°¢Çϸ®¶ó~
- À½~ Ŭ·¡½º·Î´õ°¡ ÇÊ¿äÇÏ°í, µ¿ÀûÀ¸·Î º¯°æÀÌ µÈ´Ù ÇÏ¿´À¸´Ï ¿ì¼± ÆÄÀÏÀÌ º¯°æµÈ °ÍÀ» ¾Ë¾Æ¾ßÇÑ´Ù.
- ÆÄÀÏÀÌ º¯°æµÈ °ÍÀ» üũÇÒ ¼ö ÀÖ´Â ÀÏÁ¾ÀÇ Observer thread°¡ ÇÊ¿äÇÒ °ÍÀÌ´Ù.
- º¯°æÀÌ µÇ¾ú´Ù¸é lastModified¸¦ üũÇÏ¿© ±âÁ¸ÀÇ °ª°ú ´Ù¸£´Ù¸é Ŭ·¡½º·Î´õ¸¦ »ý¼ºÇÏ¿©
ÇØ´ç Ŭ·¡½º¸¦ ·ÎµùÇÏ¿© ¼ºñ½ºÇÏ°Ô ÇÏ¸é µÉ°ÍÀÌ´Ù.
À§ÀÇ °¡Á¤¿¡¼ ÇÊ¿äÇÑ °ÍµéÀ» °¡Àå ´Ü¼øÇÏ°Ô Àû¾îº¸¾Ò´Ù.
´õ ÇÊ¿äÇÏ´Ù¸é ¿©·¯ºÐµéÀÌ ³î»õ~°¡ ÀÛ¼ºÇÑ Äڵ带 ¼öÁ¤ÇÏ¿© Å×½ºÆ®ÇØ º¸¸é µÉÅÍÀÌ°í..
ÀÚ~ À§ÀÇ ³»¿ëÀ» ÀÌ¿ëÇÏ¿© ÄÚµùÀ» Çϵµ·Ï ÇÑ´Ù.
¢º ReloadTargetClass.java
import java.net.*;
import java.io.*;
import java.util.*;
import carouser.*;
public class ClassObserver extends Thread{
static String className = "carouser.ReloadTargetClass";
long lastModified = 0;
ClassLoader cl = null;
public void observe() {
URL[] urls = null;
try {
// ÆÄÀÏ°´Ã¼¸¦ URL·Î µ¹¸°´Ù.
File dir = new File(System.getProperty("user.dir")
+File.separator+"carouser"+File.separator);
System.out.println(dir);
URL url = dir.toURL();
urls = new URL[]{url};
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
// URL·Î »ý¼ºµÈ µð·ºÅ丮¿¡ »õ·Î¿î Ŭ·¡½º·Î´õ¸¦ »ý¼ºÇϵµ·Ï ÇÑ´Ù.
ClassLoader cl = new URLClassLoader(urls);
// Àç±âµ¿ÇÒ Å¬·¡½º¸¦ ó¸®ÇÑ´Ù.
Class cls = cl.loadClass(className);
// ÇØ´ç Ŭ·¡½º¿¡ ´ëÇÑ ÀνºÅϽº¸¦ »ý¼ºÇϵµ·Ï ÇÑ´Ù.
ReloadTargetClass obj = (ReloadTargetClass)cls.newInstance();
System.out.println("Object : " + obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e2) {
e2.printStackTrace();
}
}
public void run() {
while(true) {
File target = new File(System.getProperty("user.dir")
+File.separator+"carouser"+File.separator + "ReloadTargetClass.class");
if( lastModified != target.lastModified() ) {
lastModified = target.lastModified();
System.out.println("Class Modified : " + new Date(lastModified));
observe();
}
try{
Thread.sleep(10 * 1000); // 10Ãʸ¶´Ù Çѹø¾¿ ·ÎµùÇغ»´Ù.
}catch(Exception e){}
}
}
public static void main(String [] args) {
new ClassObserver().start();
}
}
|
Äڵ尡 Àß º¸À̴°¡? ½º·¹µå¸¦ ÀÌ¿ëÇÏ¿© ÆÄÀÏÀÌ º¯°æµÇ´Â °ÍÀ» üũÇϵµ·Ï ÇÏ¿´´Ù.
¶ÇÇÑ ÆÄÀÏÀÇ º¯°æ½Ã°£À» lastModified()¸Þ¼Òµå¸¦ ÀÌ¿ëÇÏ¿© ÇØ´ç Ŭ·¡½º°¡ ´Ù½Ã
URLClassLoader¸¦ ÀÌ¿ëÇÏ¿© µ¿ÀûÀ¸·Î ·ÎµùÇϵµ·Ï ÇÏ°Ô ÇÑ´Ù.
´ë·« 10ºÐÁ¤µµ ±âÁ¸Äڵ忡 ÷°¡ÇÏ¿© ¸¸µç ÄÚµùÀ̹ǷÎ, Á¶±Ý ¹®Á¦°¡ Àֱ⵵ ÇÏ°ÚÁö¸¸
³î»õ~¿Ð : "±×·± °É·ç µýÁö °ÉÁö ¸¶¼¼¿ä~!"
¿Ö³Ä~ ±×³É ¿©·¯ºÐµéÀÌ °íÃľ²¸é ±×¸¸À̹ǷÎ.. ^^
°£´ÜÇÏÁö¸¸ ¿À¹¦ÇÏ´Ù. Äڵ带 À½¹ÌÇغ¸±â ¹Ù¶ó¸ç, ÀÀ¿ëÇؼ ÁÁÀº Ŭ·¡½º ·Î´õ¸¦ ¸¸µé¼ö ÀÖ¾î¾ß ÇÑ´Ù.
¿£Áøµé¿¡ µé¾î°¡´Â Ŭ·¡½º·Î´õµéÀº Á¤±³ÇÏ°Ô ¸¸µé¾îÁ® ÀÖ´Ù.
¢º Conclusion
Ŭ·¡½º·Î´õ¿¡ ´ëÇÏ¿© ¾ÆÁÖ¾ÆÁÖ °£´ÜÇÏ°Ô »ìÆ캸¾Ò´Ù. ³ª¸ÓÁö´Â ¿©·¯ºÐµéÀÌ ÀÀ¿ëÇϱ⠳ª¸§ÀÌ´Ù.
Âü°í·Î ´Ù½ÃÇѹø À§ÀÇ ¼Ò½º´Â classpath¿É¼ÇÀÌ »ç¿ëµÇÁö ¾Ê´Â´Ù´Â °ÍÀ» ¾Ë¾Æ¾ß Çϸç,
JSP/Servlet¿£ÁøÀ» »ç¿ëÇغ¸¾Ò´Ù¸é WEB-INF°¡ ¿Ö ±ÔÄ¢¿¡ ÀÇÇÏ¿© ±×·¸°Ô ¸¸µé¾îÁ® ÀÖ´ÂÁö¸¦
¾Ë¾Æ¾ß ÇÑ´Ù.
±Ã±ÝÇÏ¸é ¿£ÁøµéÀÇ property¸¦ Âï¾îº¸¸é Ŭ·¡½ºÆнº¸¦ Àâ±âÀ§ÇÑ °æ·Î·Î ¿©·¯ºÐµéÀÌ ¿£ÁøÀ»
¼³Ä¡ÇÑ °÷ÀÇ ${document.root}/WEB-INF/classes°¡ ÀâÇôÀÖÀ½À» ¹Ýµå½Ã ¹Ýµå½Ã ¾Ë¾Æ¾ß ÇÑ´Ù.
³¡~!! ¾Æ½Î~!
|