spring IOC 원리 와 실현

제어 반전 / 의존 주입 (회전)
IOC (DI): 사실 이 Spring 구조의 핵심 개념 은 이렇게 복잡 하지 않 고 어떤 책 에서 묘사 한 것 처럼 그렇게 어렵 지 않다.자바 프로그래머 들 은 자바 프로그램의 모든 업무 논 리 는 적어도 두 개 이상 의 대상 이 협력 하여 완성 해 야 한 다 는 것 을 잘 알 고 있 습 니 다. 일반적으로 모든 대상 이 그의 합작 대상 을 사용 할 때 자신 은 new object () 와 같은 문법 으로 합작 대상 의 신청 업 무 를 완성 해 야 합 니 다.대상 간 의 결합 도가 높다 는 것 을 알 게 될 것 이다.IOC 의 사상 은 스프링 용기 가 상호 의존 대상 의 창설, 조율 작업 을 실현 하 는 것 이다.대상 은 업무 논리 자체 와 관계 만 있 으 면 된다.그런 점 에서 대상 이 어떻게 그의 협력 대상 의 책임 을 얻 었 는 지 는 반전 됐다 (IOC, DI).
이것 은 내 가 Spring 의 IOC 에 대한 체득 이다.DI 는 사실 IOC 의 또 다른 표현 이다.DI 는 Martin Fowler 가 2004 년 초 한 논문 에서 처음 제출 한 것 이다.그 는 무엇이 반전 되 었 습 니까?의존 대상 을 얻 는 방식 이 반전 됐다 는 것 이다.
이 핵심 개념 에 대해 이해 하지 못 한다 면 브 로 몬 이라는 블 로그 에서 찾 은 알 기 쉬 운 답 을 참조 합 니 다.
IoC 와 DI
우선 IoC (Inversion of Control, 반전 제어) 에 대해 말씀 드 리 고 싶 습 니 다.이것 은 스프링 의 핵심 으로 시종일관 관통 한다.IoC 라 는 것 은 spring 프레임 워 크 에 있어 서 spring 이 대상 의 생명 주기 와 대상 간 의 관 계 를 통제 하 는 것 이다.이것 은 무슨 뜻 입 니까? 간단 한 예 를 들 어 우 리 는 어떻게 여자 친 구 를 찾 습 니까?흔히 볼 수 있 는 상황 은 우리 가 어디 에 예 쁘 고 몸매 도 좋 은 mm 가 있 는 지 여기저기 가서 그들의 취미, qq 번, 전화번호, ip 번, iq 번 을 알 아 보 는 것 이다.............................................................전통 적 인 프로그램 개발 도 마찬가지 이다. 한 대상 에서 다른 대상 을 사용 하려 면 반드시 그것 (자신 new 하나, 또는 JNDI 에서 하 나 를 조회) 을 얻어 야 한다. 사용 한 후에 대상 을 없 애 야 한다 (예 를 들 어 Connection 등). 대상 은 항상 다른 인터페이스 나 연근 과 결합 된다.
그렇다면 IoC 는 어떻게 만 들 었 을 까?마치 결혼 소개 소 를 통 해 여자 친 구 를 찾 는 것 처럼 나 와 여자 친구 사이 에 제3자: 결혼 소개 소 를 도입 했다.결혼 정보 회 사 는 많은 남녀 의 자 료 를 관리 했다. 나 는 결혼 정보 회사 에 리스트 를 제출 해서 내 가 어떤 여자 친 구 를 찾 고 싶 은 지 알려 줄 수 있다. 예 를 들 어 이 가 흔 을 닮 았 고 몸 매 는 임 희 레 를 닮 았 으 며 노래 는 주걸륜 과 같 고 속 도 는 카 를 로 스 와 같 으 며 기술 은 지단 과 같다. 그리고 결혼 정보 회 사 는 우리 의 요구 에 따라 mm 를 제공한다. 우 리 는 그녀 와 연애 만 하면 된다.결혼 하면 돼.간단명료 하 게 결혼 정보 회사 가 우리 에 게 준 인선 이 요구 에 부합 되 지 않 으 면 우 리 는 이상 을 던 질 것 이다.전체 과정 은 더 이상 내 가 통제 하 는 것 이 아니 라 결혼 정보 라 는 용기 와 유사 한 기구 가 통제 하 는 것 이다.Spring 이 제창 하 는 개발 방식 은 바로 이 렇 습 니 다. 모든 종 류 는 spring 용기 에 등록 되 어 spring 에 게 당신 이 무엇 인지 알려 줍 니 다. 당신 이 필요 로 하 는 것 이 무엇 인지 알려 줍 니 다. 그리고 spring 은 시스템 이 적당 할 때 까지 운영 되 고 당신 이 원 하 는 것 을 주동 적 으로 당신 에 게 주 는 동시에 당신 이 필요 로 하 는 다른 것 에 도 건 네 줍 니 다.모든 종류의 생 성, 폐 기 는 spring 에 의 해 제어 된다. 즉, 대상 의 생존 주 기 를 제어 하 는 것 은 더 이상 대상 을 참조 하 는 것 이 아니 라 spring 이다.어떤 구체 적 인 대상 에 대해 말하자면, 이전 에는 다른 대상 을 제 어 했 지만, 지금 은 모든 대상 이 스프링 에 의 해 제어 되 기 때문에 이것 을 제어 반전 이 라 고 한다.만약 네가 아직 이해 하지 못 한다 면, 나 는 포기 하기 로 결정 했다.
IoC 의 중점 은 시스템 운행 중 에 특정한 대상 에 게 필요 한 다른 대상 을 동적 으로 제공 하 는 것 이다.이 는 DI (Dependency Injection · 주입 의존) 를 통 해 이 뤄 진다.예 를 들 어 대상 A 는 데이터 베 이 스 를 조작 해 야 합 니 다. 예전 에 우 리 는 A 에서 스스로 코드 를 작성 하여 Connection 대상 을 얻 었 습 니 다. spring 이 있 으 면 우 리 는 spring 에 게 만 알려 야 합 니 다. A 에 Connection 이 필요 합 니 다. 이 Connection 이 어떻게 구성 되 는 지, 언제 구성 되 는 지, A 는 알 필요 가 없습니다.시스템 이 실 행 될 때 spring 은 적당 한 시기 에 Connection 을 만 들 고 주 사 를 맞 는 것 처럼 A 에 주사 하면 각 대상 간 의 관 계 를 제어 할 수 있다.A. Connection 에 의존 해 야 정상적으로 작 동 할 수 있 습 니 다. 이 Connection 은 spring 에서 A 에 주입 되 고 주입 에 의존 하 는 이름 입 니 다.그럼 디 는 어떻게 이 루어 졌 나 요?자바 1.3 이후 의 중요 한 특징 은 반사 (reflection) 이다. 프로그램 이 실 행 될 때 동적 으로 대상 을 생 성 하고 실행 대상 의 방법, 대상 의 속성 을 바 꾸 는 것 을 허용 한다. spring 은 반 사 를 통 해 주입 을 실현 한다.반사 에 관 한 자 료 는 자바 doc 를 찾 아 보 세 요.
IoC 와 DI 의 개념 을 이해 하면 모든 것 이 간단명료 해 지고 나머지 작업 은 spring 의 프레임 에 나 무 를 쌓 는 것 일 뿐이다.
아직도 모 르 겠 으 면 자바 포기 하 세 요!
스프링 이 어떻게 돌아 가 는 지 알 아 보 겠 습 니 다.

  public static void main(String[] args) {   
         ApplicationContext context = new FileSystemXmlApplicationContext(   
                  "applicationContext.xml");   
         Animal animal = (Animal) context.getBean("animal");   
          animal.say();   
      }  


이 코드 는 잘 아 시 겠 지만 분석 해 보 겠 습 니 다. 우선 applicationContext. xml 입 니 다.
  <bean id="animal" class="phz.springframework.test.Cat">   
         <property name="name" value="kitty" />   
     </bean> 


그 는 phz. spring from work. test. Cat 같은 종 류 를 가지 고 있다.

 public class Cat implements Animal {   
     private String name;   
    public void say() {   
         System.out.println("I am " + name + "!");   
   }   
     public void setName(String name) {   
         this.name = name;   
      }   
 }  

phz. springframework. test. Animal 인 터 페 이 스 를 실현 하 였 습 니 다.

 public interface Animal {   
     public void say();   
 }  


위의 코드 출력 I am kitty 가 분명 합 니 다!
그렇다면 스프링 은 어떻게 했 을 까?
이제 스프링 이 어떻게 돌아 가 는 지 직접 써 보도 록 하 겠 습 니 다!
우선, 우 리 는 Bean 클래스 를 정의 합 니 다. 이 클래스 는 Bean 이 가지 고 있 는 속성 을 저장 하 는 데 사 용 됩 니 다.
 /* Bean Id */  
    private String id;   
      /* Bean Class */  
    private String type;   
     /* Bean Property */  
    private Map<String, Object> properties = new HashMap<String, Object>();  

하나의 Bean 은 id, type, Properties 를 포함한다.
그 다음 에 Spring 은 우리 의 프로필 을 불 러 오기 시 작 했 습 니 다. 우리 가 설정 한 정 보 를 HashMap 에 저장 합 니 다. HashMap 의 key 는 Bean 의 Id 이 고 HasMap 의 value 는 이 Bean 입 니 다. 그래 야 우 리 는 context. getBean ("animal") 이라는 방법 으로 Animal 류 를 얻 을 수 있 습 니 다.Spirng 은 기본 유형 을 주입 할 수 있 고 List, Map 같은 유형 을 주입 할 수 있다 는 것 을 잘 알 고 있 습 니 다. 다음은 맵 을 예 로 들 어 Spring 이 어떻게 저장 되 는 지 살 펴 보 겠 습 니 다.
맵 설정 은 아래 와 같 을 수 있 습 니 다.

<bean id="test" class="Test">   
         <property name="testMap">   
           <map>   
                  <entry key="a">   
                   <value>1</value>   
                </entry>   
                <entry key="b">   
                     <value>2</value>   
                </entry>   
           </map>   
         </property>   
     </bean> 

Spring 은 위의 설정 을 어떻게 저장 합 니까?코드 는 다음 과 같 습 니 다:

  if (beanProperty.element("map") != null) {   
                     Map<String, Object> propertiesMap = new HashMap<String,Object>();   
                       Element propertiesListMap = (Element) beanProperty   
                              .elements().get(0);   
                     Iterator<?> propertiesIterator = propertiesListMap   
                              .elements().iterator();   
                        while (propertiesIterator.hasNext()) {   
                           Element vet = (Element) propertiesIterator.next();   
                           if (vet.getName().equals("entry")) {   
                              String key = vet.attributeValue("key");   
                             Iterator<?> valuesIterator = vet.elements()   
                                    .iterator();   
                              while (valuesIterator.hasNext()) {   
                                  Element value = (Element) valuesIterator.next();   
                                if (value.getName().equals("value")) {   
                                       propertiesMap.put(key, value.getText());   
                                 }   
                                 if (value.getName().equals("ref")) {   
                                      propertiesMap.put(key, new String[] { value   
                                            .attributeValue("bean") });   
                                  }   
                              }   
                        }   
                     }   
                      bean.getProperties().put(name, propertiesMap);   
                  }

다음은 가장 핵심 적 인 부분 에 들 어 갑 니 다. Spring 이 어떻게 주입 에 의존 하 는 지 살 펴 보 겠 습 니 다. 사실은 주입 에 의존 하 는 사상 도 간단 합 니 다. 반사 체 제 를 통 해 이 루어 진 것 입 니 다. 하나의 유형 을 예화 할 때 반사 호출 류 에서 set 방법 으로 HashMap 에 존재 하 는 유형 속성 을 클래스 에 주입 합 니 다.그것 이 어떻게 하 는 지 구체 적 으로 봅 시다.
우선 하나의 종 류 를 예화 하여 이렇게 하 다.

   public static Object newInstance(String className) {   
           Class<?> cls = null;   
           Object obj = null;   
          try {   
              cls = Class.forName(className);   
              obj = cls.newInstance();   
          } catch (ClassNotFoundException e) {   
              throw new RuntimeException(e);   
          } catch (InstantiationException e) {   
               throw new RuntimeException(e);   
          } catch (IllegalAccessException e) {   
              throw new RuntimeException(e);   
          }   
           return obj;   
       }  

이어서 이 종류의 의존 을 주입 시 켜 이렇게

 public static void setProperty(Object obj, String name, String value) {   
        Class<? extends Object> clazz = obj.getClass();   
          try {   
              String methodName = returnSetMthodName(name);   
            Method[] ms = clazz.getMethods();   
            for (Method m : ms) {   
                 if (m.getName().equals(methodName)) {   
                       if (m.getParameterTypes().length == 1) {   
                        Class<?> clazzParameterType = m.getParameterTypes()[0];   
                           setFieldValue(clazzParameterType.getName(), value, m,   
                                  obj);   
                         break;   
                     }   
                  }   
            }   
         } catch (SecurityException e) {   
              throw new RuntimeException(e);   
           } catch (IllegalArgumentException e) {   
               throw new RuntimeException(e);   
         } catch (IllegalAccessException e) {   
              throw new RuntimeException(e);   
          } catch (InvocationTargetException e) {   
              throw new RuntimeException(e);   
          }   
   }

마지막 으로 그것 이 이 종류의 실례 를 우리 에 게 되 돌려 주면 우 리 는 사용 할 수 있다.우 리 는 맵 을 예 로 들 어 그것 이 어떻게 하 는 지 보 겠 습 니 다. 제 가 쓴 코드 에는 HashMap 을 만 들 고 이 HashMap 을 주입 할 클래스 에 주입 하 는 것 입 니 다. 이렇게...

  if (value instanceof Map) {   
                  Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()   
                            .iterator();   
                   Map<String, Object> map = new HashMap<String, Object>();   
                   while (entryIterator.hasNext()) {   
                       Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();   
                      if (entryMap.getValue() instanceof String[]) {   
                          map.put((String) entryMap.getKey(),   
                                  getBean(((String[]) entryMap.getValue())[0]));   
                      }   
                  }   
                  BeanProcesser.setProperty(obj, property, map);   
               }  

자, 이렇게 하면 우 리 는 Spring 로 우리 에 게 만들어 준 클래스 를 만 들 수 있 습 니 다. 어렵 지 않 습 니까?물론 Spring 이 할 수 있 는 것 은 이것 뿐만 이 아니다. 이 예제 프로그램 은 Spring 의 가장 핵심 적 인 의존 주입 기능 중의 일부분 만 제공 했다.
본 고 는 대량의 글 을 참고 하여 일일이 감사 할 수 없습니다. 여기 서 감 사 드 립 니 다. 만약 당신 의 저작권 을 침해 한 것 에 대해 깊 은 사 과 를 드 립 니 다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기