2012-02-24 3 views
1

Java에서 사용자 정의 주석을 작성하는 방법을 배우려고합니다.다른 객체를 주입하는 Java 사용자 정의 주석

학습을 위해 필자는 주석을 사용하여 클래스에 필드를 사용할 수있게 만드는 주석을 작성하기로 결정했습니다. 즉 주입 : 간단하지만 주입을 단순화하기 위해 필요하지는 않지만 그것은 또한 환영 받는다.

=============== 클래스 1 ========= ========================

import java.lang.annotation.ElementType; 
import java.lang.annotation.Inherited; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 


@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
public @interface AutoInject { 

} 

=================== ============== CLASS 2 ==================== =

// The class to be injected in Main.java 
public class TestClass0 { 

    void printSomething(){ 
     System.out.println("PrintSomething: TestClass0"); 
    } 

} 

================================= CLASS 3 ===== ===============

import java.lang.annotation.Annotation; 
import java.lang.reflect.Field; 

public class Main { 

    TestClass0 ts0; 
    // Injecting here!! 
    @AutoInject 
    public TestClass0 getTso() { 
     return ts0; 
    } 
    public void setTso(TestClass0 ts) { 
     ts0 = ts; 
    } 

    public static void main(String[] args) { 
     performAnnotationScanOnClass (Main.class); 

     // Create instance 
     Main main = new Main();  
     main.getTso().printSomething(); 

    } 

    public static void performAnnotationScanOnClass(Class<?> clazz) { 
     Field[] fields = clazz.getDeclaredFields(); 

     for (Field field : fields) { 

      Annotation[] annotations = field.getAnnotations(); 
      for (Annotation annotation : annotations) { 

       if (annotation instanceof AutoInject) { 
        AutoInject autoInject = (AutoInject) annotation; 

//      if (field.get(...) == null) 
//       field.set(... , value) 
       } 

      } 

     } 
    } 

} 

정적 보들 main()에서 볼 수 있듯이, TestClass0에서 메서드를 호출하려고합니다. 사용 가능할 것으로 예상됩니다. 위의 내용은 거의 완성 된 것입니다.하지만 방금 주석을 배우기 시작했고 귀하의지도를 원합니다.

우리는 어떻게 새로운 또는 get 메소드가 호출에 속성 중 하나를 initializez 코드 조각을 발사 할 수 있습니다. 주석 사용. 나는 을 변경하지 않고 메서드를 호출하지 않고 생각하고있다.

감사합니다.

+0

당신은 당신의 테스트 주석을 생각하지만, 당신이 정말로 CDI를 개혁하고 있습니다. 바퀴를 재발견하지 마라. – Perception

+6

나는 아무것도 재발 명하지 않는다. 나는 다른 사람들이 무엇을 어떻게 획득하고 창조했는지를 배우려고 노력하고있다. 그 차이를 이해하니? 그것의 교육 목적을 위해. – momomo

+0

좋아, 그럼 그걸로 행운을 빈다! 나는 당신이 많이 배울 것이라고 확신합니다. – Perception

답변

3

스캔 코드의 필드를 반복하고 있지만 정의한 주석은 메소드의 주석 만 허용합니다. 즉, 아무런 특수 효과도 볼 수 없습니다.

Java Bean 속성과 같은 필드를 사용하려는 것 같습니다.

Main.java : 여기있는 그대로 당신의 AutoInject 및 TestClass0 클래스를 사용하여 세터 주입의 예

import java.beans.BeanInfo; 
import java.beans.Introspector; 
import java.beans.PropertyDescriptor; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Method; 

public class Main { 
    public TestClass0 ts0; 

    public TestClass0 getTso() { 
     return ts0; 
    } 

    @AutoInject 
    public void setTso(TestClass0 ts) { 
     ts0 = ts; 
    } 

    public static void main(String[] args) { 
     // Create instance 
     Main main = new Main(); 
     injectDependencies(main).getTso().printSomething(); 

    } 

    public static <T> T injectDependencies(final T obj) { 
     try { 
      Class clazz = obj.getClass(); 
      BeanInfo beanInfo = Introspector.getBeanInfo(clazz); 

      for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) { 
       Method readMethod = pd.getReadMethod(); 
       Method writeMethod = pd.getWriteMethod(); 

       if (writeMethod == null) { 
        continue; 
       } 

       Object existingVal = pd.getReadMethod().invoke(obj); 
       if (existingVal == null) { 
        for (Annotation annotation : writeMethod.getAnnotations()) { 
         if (annotation instanceof AutoInject) { 
          Class propertyType = pd.getPropertyType(); 
          writeMethod.invoke(obj, propertyType.newInstance()); 
         } 
        } 
       } 
      } 
     } catch (Exception e) { 
      // do something intelligent :) 
     } 
     return obj; 
    } 

} 
+0

안녕하세요, 좋아 보이지만 메인의 실제 객체를 전달 중입니다. 새로운 주 객체를 만들면 그 방법을 상기해야합니다. 맞습니까? 예를 들어 Spring injection을 살펴보면, 새로운 Main()을 할 때 자동으로 주입되는 종속물 (보통 싱글 톤 객체)이 생깁니다. 아이디어는 모든 클래스 파일을 한 번 (시작시) 스캔하여 각각의 새 오브젝트에 추가 된 동작을 추가하는 것입니다. – momomo

+0

Spring은 모든 객체 (ApplicationContext)를 생성/전달하기 위해 중앙 컨텍스트를 사용합니다. 어노테이션 관련 코드가 어떻게 작동 하는지를 설명하려고 했으므로 내 코드는 그렇지 않습니다. 이 메인 클래스에 묶여있는 인젝션 코드에 대해서는 아무 것도 없습니다. 여러분의 구성을 읽고 객체 생성/서비스 위치에 대한 요청을받는 자신 만의 인젝터 클래스에 쉽게 삽입 할 수 있습니다. – gorjusborg

관련 문제