본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Java] Reflection Tutorial - Dynamic Class Loading and Reloading.

by 돼지왕왕돼지 2014. 1. 9.
반응형


 Java, Reflection Tutorial - Dynamic Class Loading and Reloading.  

[Java] Reflection Tutorial - Dynamic Class Loading and Reloading.


Java 에서 dynamic 하게 class 를 load 혹은 reload 할 수 있다.



The ClassLoader


Java 의 모든 class 는 ClassLoader의 subclass 를 이용하여 로드된다.

한 class 가 load 될 때 다른 연관된 ( refer 된 ) class 들도 모두 함께 recursive 하게 load 된다.




The ClassLoader Hierachy


새로운 class loader 를 작성할 떄면 반드시 Java 의 기본 ClassLoader 를 상속하여 이용해야 한다. 먼저 parent ClassLoader 를 이용하여 load 를 시도하고, parent 가 class 를 찾을 수 없다면, child class loader 가 load 를 시도하는 방식이다.




Class Loading


class loading 은 다음과 같은 절차로 이루어진다.


1. class 가 이미 load 되어 있는지 확인

2. 만약 load 안 되어있다면, parent class 에게 load 하도록 요구

3. parent class loader 가 해당 class 를 load 할 수 없다면, 자식 class 가 load 를 시도.




Dynamic Class Loading


class loading 은 ClassLoader 를 얻어서 loadClass() 를 호출하는 것 뿐이다.


ClassLoader classLoader = AClass.class.getClassLoader();

Class aClass = classLoader.loadClass( "com.example.AClass" );




Dynamic Class Reloading


Java 의 built in classloader 를 사용하면 reload 를 할 수 없다.

이유는 built in classloader 는 class 가 이미 load 되었는지 확인하기 때문.


만약 reload 를 하고자 하는 class loader 가 아닌 다른 class loader 에서 reload 를 하면, 이렇게 생성된 class들은  package name + class name 을 가지고 있더라도, ClassCastException 이 발생한다. 다른 녀석으로 간주하기 때문.


그래서 다음과 같은 방법으로 reloading 을 할 수 있다.


방법 1. variable type 으로 interface 를 사용하여 implementing 하며 reloading.

방법 2. superclass 를 variable type 으로 사용하여 바로 reload.


MyObject object = (MyObject) myClassReloadingFactory.newInstance( "com.example.MyObject" );


MyObjectInterface object = (MyObjectInterface) myClassReloadingFactory.newInstance( "com.example.MyObject" );

MyObjectSuperClass object = (MyObjectSuperClass) myClassReloadingFactory.newInstance( "com.example.MyObject" );







ClassLoader Load / Reload Example


public class MyClassLoader extends ClassLoader{


    public MyClassLoader(ClassLoader parent) {

        super(parent);

    }


    public Class loadClass(String name) throws ClassNotFoundException {

        if( !"reflection.MyObject".equals( name ) )

                return super.loadClass( name );


        try {

            String url = "file:C:/java/projects/classloader/classes/reflection/MyObject.class";

            URL myUrl = new URL(url);

            URLConnection connection = myUrl.openConnection();

            InputStream input = connection.getInputStream();

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            int data = input.read();


            while(data != -1){

                buffer.write(data);

                data = input.read();

            }


            input.close();


            byte[] classData = buffer.toByteArray();


            return defineClass("reflection.MyObject", classData, 0, classData.length);


        } catch (MalformedURLException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace(); 

        }


        return null;

    }


}


public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {


    ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();

    MyClassLoader classLoader = new MyClassLoader( parentClassLoader );

    Class myObjectClass = classLoader.loadClass( "reflection.MyObject" );


    AnInterface2 object1 = (AnInterface2) myObjectClass.newInstance();

    MyObjectSuperClass object2 = (MyObjectSuperClass) myObjectClass.newInstance();


    //create new class loader so classes can be reloaded.

    classLoader = new MyClassLoader( parentClassLoader );

    myObjectClass = classLoader.loadClass( "reflection.MyObject" );


    object1 = (AnInterface2) myObjectClass.newInstance();

    object2 = (MyObjectSuperClass) myObjectClass.newInstance();

}


public class MyObject extends MyObjectSuperClass implements AnInterface2{

    //... body of class ... override superclass methods

    //    or implement interface methods

}



참고 사이트 : http://zeroturnaround.com/rebellabs/reloading-objects-classes-classloaders/






반응형

댓글0