== 스프링 학습> IOC [제어 반전]

I. 개요

봄의 세 가지 핵심 아이디어 : IOC의 (제어의 반전), DI (의존성 주입), AOP (Aspect 지향적 인 프로그래밍). 이 이야기는 제어의 반전에 대해 질문 초점을 맞추고있다.

컨트롤의 어떤 반전 : 봄은 느슨하게라는 반전 (IOC의) 제어 기술에 의해 결합 용이. 당신은 IOC의 수동적 통해 전달됩니다 다른 개체에 따라 객체가 아니라 그 자체가 만들거나 종속 개체를 찾을 수있는 개체를 적용 할 때. 컨테이너에서 종속성을 찾아하는 것이 목적이 아니라 요청에 이르기까지 컨테이너 객체가 전달 된 이니셔티브에 따라 달라집니다 경우 개체가 초기화 - 당신은 IOC의와 JNDI 반대 생각할 수 있습니다.

인기 말하기, 코드에 의해 외부 용기를 제어 할 수있는 권리, 전송, 소위 반전의 제어. 즉, 우리는 새로운 개체, 새로운 정상, 당신은 객체를 호출 할 수 있습니다. 제어의 반전이 필요하지 않습니다으로 관리 할 수있는 컨테이너에, 우리는 단지 구성의 숫자를 통해 이러한 프로세스 컨테이너에 엔티티 클래스를 완료해야합니다. 이 코드의 복잡성의 양을 줄이고 커플 링 개발을 단순화.

둘째, 지향 프로그래밍 인터페이스

객체 지향 시스템에서, 시스템의 다양한 기능은 공동으로 수행 여러 개체로 구성된다. 이 경우, 각각의 내부 오브젝트 시스템 설계자의 관점에서 자신을 달성하는 방법을 그렇게 중요하지 않습니다이며, 다양한 개체 사이의 협력 관계는 키 시스템 설계이다. 상이한 클래스 간의 통신 소형 시스템 설계의 시작에서 모듈 사이의 상호 작용뿐만 아니라 대형 시스템 설계의 주요 작업이다 중요한 고려 사항이다. 지향 프로그래밍 인터페이스는 이러한 생각에 따른 프로그래밍을 말한다.

발신자에 대한 특정 인터페이스에 대한 구체적인 지향 프로그래밍 인터페이스, 우리는 단순히 호출자에게 인터페이스를 제공하는 방법을 특정 달성하기 위해 인터페이스의 구현이 클래스에 의해 구현되는 신경,도이다 상관 없어 그것.

셋째, 코딩 IOC의

여기서 우리는 간단한 인터페이스 지향 프로그래밍을 구현하는 IOC의 아이디어를 사용합니다.

우선 다음과 같이 두 개의 인터페이스와 IAccountService IOrderService 정의 :

공용  인터페이스 IAccountService { 

  INT insertAccount (문자열 MSG); 

}
IAccountService 인터페이스
공용  인터페이스 IOrderService { 

  무효 삽입 (문자열 MSG); 

}
IOrderService 인터페이스

그런 다음,이 두 정의 된 클래스는 인터페이스를 구현하는

공공  클래스 AccountBigServiceImpl는 구현 IAccountService { 

  @Override 
  공공  INT insertAccount (문자열 MSG) { 

    에서 System.out.println ( "===== AccountBigServiceImpl ===="+ MSG를); 

    반환 0 ; 
  } 
}
AccountBigServiceImpl
공공  클래스 AccountSamllServiceImpl는 구현 IAccountService { 

  @Override 
  공공  INT insertAccount (문자열 MSG) { 

    에서 System.out.println ( "smallService을" ); 

    반환 0 ; 
  } 
}
AccountSamllServiceImpl
공공  클래스 있으며, OrderServiceImpl는 구현 IOrderService { 

  @Override 
  공공  무효 삽입 (문자열 MSG) { 

    에서 System.out.println ( "===== 있으며, OrderServiceImpl ===="+ MSG를); 
  } 
}
있으며, OrderServiceImpl

우리는 일반적으로이 두 가지 인터페이스를 호출하는 다음 코드를 사용하여

공용  클래스 컨트롤러 {
   공공  정적  무효 메인 (문자열 []에 args) { 
    IAccountService위한 AccountService = 새로운 AccountBigServiceImpl (); 
    accountService.insertAccount ( "안녕하세요!" ); 

    IOrderService는 OrderService = 새로운 있으며, OrderServiceImpl (); 
    orderService.insert ( "세계!" ); 
  } 
}

AccountBigServiceImpl하고 있으며, OrderServiceImpl : 우리는이 클래스의 새로운 IAccountService 및 IOrderService이 개 서브 클래스 컨트롤러 인터페이스를 직접. 위에서 언급 한에 대한 프로그래밍 인터페이스이 아이디어는 달리, 나는 단지이 클래스에서 비즈니스 로직 컨트롤러를 처리하기를 원하지만 위가 AccountBigServiceImpl을 구현하는이 클래스를 사용하는 사람 IAccountService 및 IOrderService 두 개의 인터페이스 특정 범주에 대한도 우려 나는이 인터페이스를 구현하는이 AccountSamllServiceImpl 구현 클래스를 사용하려면 인터페이스 IAccountService는 그때 그때 우리는 다른 생각할 수있는, 분명히 유지 보수 비용이 실수를 아주 쉽게 또한 너무 높은되지만, 일, 컨트롤러의 코드를 수정해야 방법.

첫째, 우리는 구현 클래스의 두 점의 인터페이스를 정의하기 위해 구성 파일을 사용하여

IAccountService = com.jack.course.spring.factory.impl.AccountBigServiceImpl 
IOrderService = com.jack.course.spring.factory.impl.OrderServiceImpl
conf.properties

그런 다음, 우리는 클래스 팩토리를 정의 할 것이다

공공  클래스 ServiceFactory { 

  개인  정적  최종 문자열 CONF_FILE_NAME = "공장 /를 conf.properties" ; 

  개인  정적 속성 소품, 

  개인  정적 지도 <문자열, 개체> beanContainer; 

  / ** 
   * 정적 코드 블록 만 프로그램 실행 후로드됩니다 
   * / 
  정적 { 

    은 try { 
      beanContainer = Maps.newHashMap ();
       // 1. 구성 파일에서이 관계 알아내는 
      소품 = 새로운 새로운 속성 (); 
      prop.load합니다 (ServiceFactory의. 클래스 .getClassLoader ()을 같이 getResourceAsStream (CONF_FILE_NAME).); 
    }캐치 (예외 : IOException 전자) {
       던져  새로운 IllegalArgumentException가 (전자); 
    } 
  } 

  공용  정적 <T> T의 getService (클래스 <T> 를 clazz) { 

    경우 (beanContainer.containsKey (clazz.getSimpleName ())) {
       (T) beanContainer.get (clazz.getSimpleName ()); 
    } 

    시도 {
       // 2.根据关系,将具体的实现类返回 
      객체 OBJ = instanceObj (clazz에를); 
      beanContainer.put (clazz.getSimpleName (), OBJ); 
      (T) OBJ; 
    } 캐치 (예외 전자) {
       던져  새로운  IllegalArgumentException가 (전자);
    } 
  }

   개인  정적 <T> instanceObj (클래스 <T>를 clazz) 개체 발생 예외 { 
    문자열 클래스 명 = prop.getProperty (clazz.getSimpleName ()); 
    클래스 <?> = 인스턴스 가 Class.forName (클래스 명);
    복귀 ) (instance.newInstance 단계; 
  } 
}

참고 : 위의 코드는 두 개의 최적화 작업을 수행합니다. 우선, 조작 번만 반복하지 않는다 판독 코드의 정적 블록으로 석출하는 구성 파일이 판독한다. 컨테이너가 객체가 이미 직접 객체의 인스턴스를 instanceObj () 메소드에 의해하지 반환 재현 할 수있는 존재 인스턴스화 및 2로되어있는 경우 둘째, 객체 클래스의 정의는 빈지도 저장 용기로 인스턴스화 최적화에서 성능을 크게 향상시킬 수 있습니다.

이 기능은 공장 클래스 구현됩니다, 패스 컨트롤러를 생성하는 객체에 의해 구성 파일 conf.properties을 읽어 획득 인터페이스 구현 클래스를 다음 반영 구현 클래스 인터페이스 누가 상관 없습니다 Controller 클래스, 어떻게 그렇게 그들은 상관하지 않습니다 알고 있습니다.

그래서 우리는 컨트롤러를 달성 할 수

공용  클래스 컨트롤러 {
   공공  정적  무효 메인 (문자열 []에 args) { 

    IAccountService위한 AccountService = ServiceFactory.getService (IAccountService. 클래스 ); 
    accountService.insertAccount ( "안녕하세요!" ); 

    IOrderService orderService1 = ServiceFactory.getService (IOrderService. 클래스 ); 
    IOrderService orderService2 = ServiceFactory.getService (IOrderService. 클래스 ); 
    orderService1.insert ( "하나" ); 
    orderService2.insert ( "2" ); 
  } 
}

따라서, 우리는 코드를 수정하지 않습니다 만 라인의 구성 파일을 수정해야, 그런 종류를 달성하기 위해 변경하려는 경우.

결과는 다음과 같습니다 :

위, 우리는 IOC의 아이디어를 통해 인터페이스 지향 프로그래밍을 구현합니다. 그러나 우리는이 완전히 문제가되지 않습니다 실현?

우리는 약간 AccountBigServiceImpl 구현 클래스의 기본 생성자를 오버라이드 (override) 증가 생성자 매개 변수를 수정

공공  클래스 AccountBigServiceImpl는 구현 IAccountService { 

  개인 AccountBigServiceImpl (문자열 MSG) { 
    에서 System.out.println (MSG)를; 
  } 

  @Override 
  공공  INT insertAccount (문자열 MSG) { 

    에서 System.out.println ( "===== AccountBigServiceImpl ===="+ MSG); 

    반환 0 ; 
  } 
}

그리고 컨트롤러를 수행 오류 일 것이다. 우리가 newInstance와를 사용하면 객체가 인수가없는 기본 생성자입니다 인스턴스화하기 때문이다.

그래서, 우리는 공장 클래스를 수정,이 기능을 구현할 수 있습니다. 그러나, 당신은 또한 천천히, 우리 자신을 모두 달성하지 않을 다른 문제가있는 것을 알 수 있습니다, 우리는 직접 스프링 프레임 워크가 될 수 있습니다 사용할 수 있습니다. 우리는 스프링 프레임 워크 생각할 수있는 예상치 못한 기능은, 우리가 그냥 직접 사용 실현했다.

XML 파일의 사용은 IOC의를 구성합니다

 

다섯째, IOC의를 구성하는 주석 + XML 파일을 사용하여

 

여섯째, 전체 주석 구성의 IoC를 사용

 

추천

출처www.cnblogs.com/L-Test/p/11593641.html