제어의 역행(IoC, Inversion of Control) 
객체, 메서드 호출시 처리하지않고 외부(spring)에서 처리한다. 
블럭 끼워넣기 개발이라고도 칭함 
의존성 주입(DI, Dependency Injection) 
제어의 역행이 발생할 때, 스프링 내부에 있는 객체가 해당 클래스를 사용할 때 필요한 관계를 관리하는 동작 또는 기법 
여기서 의존성이란 객체가 혼자서는 처리할 수 없음을 뜻한다.
따라서 객체를 직접 생성해서 구현한다 ex) jsp model2에서의 DAO객체생성 
관계를 약화시키면서 간접 구현 즉 호출해야한다. 
 
 
따라서 의존성 주입이란 객체를 직접 생성/제어하는 것이 아니라, 제어의 역행을 사용해서 특정 객체를 필요한 객체의 외부에 가져다가 연결하는 것을 뜻한다. 
객체가 필요한 어떤 객체를 생성자 혹은 setter를 통해 주입하는 것을 말한다. 
예를 들어 사람이란 객체가 있다. 머리, 몸통, 팔, 다리부분으로 구성되어있는 객체이다. 여기서 머리만 바꿔끼우면(= 주입) 사람A에서 사람B가 될 수 있다. 
 
의존성 주입 3가지 방법 스프링 프레임워크는 @Autowired 애노테이션을 이용하여 다양한 의존성주입방법을 제공한다.@Autowired 애노테이션은 Spring에게 의존성을 주입하라는 지시자 역할로 쓰이는데 생성자, 필드, 세터에 붙일 수 있다.
생성자 주입
@Autowired 애노테이션 생략가능 -> lombok을 활용해 @ReqyiredArgsConstructor와 상수 조합1 2 3 4 5 @RestController @ReqyiredArgsConstructor public  class  ApiController 	private  final  UserService service; } 
 
 
 
필드 주입: 변수 선언부에 @Autowired 애노테이션을 붙인다.
가장 편리한 방법이면서 실무에서 자주 사용하는 주입 방법1 2 3 4 5 @RestController public  class  ApiController 	@Autowired  	private  UserService service; } 
 
 
 
수정자 주입(Setter): Setter 메소드에 @Autowired 애노테이션을 붙인다.  1 2 3 4 5 6 7 8 9 @Component public  class  ApiController  	private  UserService userService; 	@Autowired  	public  void  setUserService (UserService userService)   		this .userService = userService; 	} } 
 
위의 세가지 방법 중 spring에서 권장하는 방법은 생성자를 통한 주입 방법이다.
어노테이션을 쓰지않고 xml을 이용한 DI 1 생성자를 이용한 예시 
.xml파일에 spring beans DTD 연결.xml파일의 <bean>태그로 객체생성하기 (new 키워드랑 동일한 결과)
constructor-arg : “생성자 사용해서 값 주입” 
원하는 파라미터 갯수만큼 <constructor-arg>태그생성
태그 생성시 순서 : 파라미터 순서그대로 대입됨 
 
 
student.xml 코드value담는 방식은 두가지 1. <value>태그사용 2.value=""속성사용1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans  PUBLIC  "-//SPRING//DTD BEAN//EN"  "http://www.springframework.org/dtd/spring-beans.dtd" > <beans > 	<bean  id ="studentBean"  class ="com.itwill.spring.ItwillStudent" >  		<property  name ="name"  value ="홍길동" > </property >  		<property  name ="classNum" > <value > 7</value > </property >  	</bean >  	 	 	<bean  id ="conBean1"  class ="com.itwill.spring.ItwillStudent" >   		<constructor-arg >  			<value > 사용자3</value >  		</constructor-arg >  	</bean >  	<bean  id ="conBean2"  class ="com.itwill.spring.ItwillStudent" >   		<constructor-arg  value ="사용자4"  />  		<constructor-arg  value ="1"  />  	</bean >  </beans > 
 
 
 
Student.java 인터페이스 생성 
1 2 3 4 5 public  interface  Student  	 	public  void  showInfo ()  	 } 
ItwillStudent.java 생성 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public  class  ItwillStudent  implements  Student 	private  String name; 	private  int  classNum; 	 	 	public  ItwillStudent ()  	public  ItwillStudent (String name)  		this .name = name; 	} 	public  ItwillStudent (String name,int  classNum)  		this .name = name; 		this .classNum = classNum; 	} 	 	 	public  void  setName (String name)   		this .name = name; 	} 	public  void  setClassNum (int  classNum)   		this .classNum = classNum; 	} 	 	@Override  	public  void  showInfo ()   		System.out.println("이름: "  + name + ", 강의장: "  + classNum); 	} 	@Override  	public  String toString ()   		return  "toString [이름: "  + name + ", 강의장: "  + classNum + "]" ; 	}	 } 
StudentTest.java 코드 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public  class  StudentTest  	public  static  void  main (String[] args)   		 		ItwillStudent kim = new  ItwillStudent(); 		kim.setName("킴스" ); 		kim.setClassNum(8 ); 		kim.showInfo(); 		 		System.out.println("-----생성자 사용하여 객체생성" ); 		 		ItwillStudent user1 = new  ItwillStudent("사용자1" ); 		user1.showInfo(); 		Student user2 = new  ItwillStudent("사용자2" , 7 ); 		user2.showInfo(); 		 		System.out.println("-----생성자 사용하여 DI" ); 		 		ItwillStudent user3 = (ItwillStudent) fac.getBean("conBean1" ); 		user3.showInfo(); 		ItwillStudent user4 = (ItwillStudent) fac.getBean("conBean2" ); 		user4.showInfo(); 		 	} } 
2 수정자 Setter메서드 이용한 예시 
.xml파일에 spring beans DTD 연결
.xml파일의 <bean>태그로 객체생성하기 (new 키워드랑 동일한 결과)
bean태그에서 사용할 수 있는 속성들 
id : “빈 객체의 고유한 이름, 외부에서 접근하는 이름” 
name : “객체의 별칭” 
class : “생성할 클래스위치” 
property : “set() 사용해서 값을 주입”
name속성 : bean태그의 class속성 위치에 있는 클래스의 멤버변수 중에 set 원하는 것을 지정  
value담는 방식은 두가지 1. <value>태그사용 2.value=""속성사용 
 
 
constructor-arg : “생성자 사용해서 값 주입” 
person.xml 코드1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans  PUBLIC  "-//SPRING//DTD BEAN//EN"  "http://www.springframework.org/dtd/spring-beans.dtd" > <beans > 	 	<bean  id ="personBean"  class ="com.itwill.spring.SubPerson" >  		 		<property  name ="name" > <value > 아이린</value > </property >  		<property  name ="age"  value ="25" > </property >  	</bean >  </beans > 
 
IPerson.java 인터페이스생성
 
1 2 3 4 5 6 public  interface  IPerson  	 	 	 	public  void  sayHello ()  } 
SubPerson.java 파일 생성 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public  class  SubPerson  implements  IPerson  	 	private  String name; 	private  int  age; 	 	public  String getName ()   		return  name; 	} 	public  void  setName (String name)   		this .name = name; 	} 	public  int  getAge ()   		return  age; 	} 	public  void  setAge (int  age)   		this .age = age; 	} 	 	@Override  	public  void  sayHello ()   		System.out.println(name+"님(" +age+"세), 안녕하세요!" ); 	} 	 	@Override  	public  String toString ()   		return  "SubPerson정보 [이름="  + name + ", 나이="  + age + "]" ; 	} } 
PersonTest.java파일에서 객체 사용하기
BeanFactory는 외부의 파일을 읽어와서 처리함 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public  class  PersonTest  	 	public  static  void  main (String[] arg)  	 		 		Person p1 = new  Person(); 		p1.setName("홍길동" ); 		p1.setAge(20 ); 		 		System.out.println(p1); 		System.out.println(p1.toString()); 	 		 		 		SubPerson sp = new  SubPerson(); 		sp.setName("소미" ); 		sp.setAge(22 ); 		sp.sayHello(); 		 		 		BeanFactory fac = new  XmlBeanFactory(new  FileSystemResource("person.xml" ));  		 		IPerson ip = (IPerson) fac.getBean("personBean" );  		ip.sayHello(); 	} } 사용자정보 [이름=홍길동, 나이=20 ] 사용자정보 [이름=홍길동, 나이=20 ] 소미님(22 세), 안녕하세요! log4j:WARN No appenders could be found for  logger  (org.springframework.beans.factory.xml.XmlBeanDefinitionReader) .  log4j:WARN Please initialize the log4j system properly. log4j:WARN See http: 아이린님(25 세) , 안녕하세요! 
강한 결합 VS 약한 결합 
JPA에서 주로 사용하는 DI 방법은? 빌더 패턴을 사용하기를 권장하고 있다.생성패턴의 종류와 빌더패턴을 사용해야하는 이유 포스팅에서 확인할 수 있다.