Spring Injection : 스프링 컨테이너에 의해 Spring Bean Configuration File에 등록된 클래스로 객체(Spring Bean) 생성시 필드에 원하는 값 또는 객체를 저장되도록 설정
package xyz.itwill05.di;
public class Student {
private int num;
public String name;
public String email;
public Student() {
System.out.println("### Student 클래스의 기본 생성자 호출 ###");
}
public Student(int num) {
super();
this.num = num;
System.out.println("### Student 클래스의 매개변수(학번)가 선언된 생성자 호출 ###");
}
/*
public Student(String name) {
super();
this.name = name;
System.out.println("### Student 클래스의 매개변수(이름)가 선언된 생성자 호출 ###");
}
*/
public Student(int num, String name) {
super();
this.num = num;
this.name = name;
System.out.println("### Student 클래스의 매개변수(학번,이름)가 선언된 생성자 호출 ###");
}
public Student(int num, String name, String email) {
super();
this.num = num;
this.name = name;
this.email = email;
System.out.println("### Student 클래스의 매개변수(학번,이름,이메일)가 선언된 생성자 호출 ###");
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
System.out.println("*** Student 클래스 setNum(int num) 메소드 호출 ***");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("*** Student 클래스 setName(String name) 메소드 호출 ***");
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
System.out.println("*** Student 클래스 setEmail(String email) 메소드 호출 ***");
}
@Override
public String toString() {
return "학번 = "+num+", 이름 = "+name+", 이메일 = "+email;
}
}
- Spring Bean으로 등록된 클래스의 기본 생성자를 이용하여 객체 생성
- 객체의 필드에는 기본값(숫자형 : 0, 논리형 : false, 참조형 : null) 저장
- Spring Bean으로 등록된 클래스의 매개변수가 선언된 생성자를 이용하여 객체 생성
- bean 엘리먼트의 하위 엘리먼트를 사용하여 생성자 매개변수에 값을 전달하여 필드값으로 저장
Constructor Injection : 생성자를 이용하여 객체 필드 초기화 작업 실행
Value Injection : 객체의 필드에 값이 저장되도록 초기화 작업 실행 (값 주입)
index 속성 : 생성자 매개변수에 값(객체)을 전달하기 위한 순서를 속성값으로 설정
<constructor-arg value="홍길동" index="1"/>
- Setter Injection
- 클래스의 기본 생성자를 이용하여 객체 생성 (객체 필드에는 기본값 저장)
- 하위 엘리먼트 사용하여 Setter 메소드를 호출해 필드값 변경
property : 객체의 Setter 메소드를 호출하여 필드값을 변경하는 엘리먼트
<property name="email" value="xyz@itwill.xyz"/>
- 생성자(Constructor Injection)와 Setter 메소드(Setter Injection)를 같이 사용하여 객체 초기화 작업 가능
- PropertyPlaceholderConfigurer 클래스 : Properties 파일을 제공받아 파일에 설정된 값을 Spring Bean Configuration File에서 사용할 수 있도록 제공하는 클래스
- locations 필드에 Properties 파일의 경로를 전달하여 저장
- Properties 파일에 의해 제공되는 값은 Spring Bean Configuration File에서 ${이름}으로 사용
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations" value="xyz/itwill05/di/student.properties"/>
(파일경로로 작성)<property name="num" value="${num}"/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Spring Bean으로 등록된 클래스의 기본 생성자를 이용하여 객체 생성 -->
<!-- => 객체의 필드에는 기본값(숫자형 : 0, 논리형 : false, 참조형 : null) 저장 -->
<bean class="xyz.itwill05.di.Student" id="student1"/>
<!-- Spring Injection : 스프링 컨테이너에 의해 Spring Bean Configuration File에 등록된
클래스로 객체(Spring Bean) 생성시 필드에 원하는 값 또는 객체를 저장되도록 설정 -->
<!-- => 생성자(Constructor Injection) 또는 Setter 메소드(Setter Injection)를 이용하여 값
또는 객체를 필드에 저장 -->
<!-- Spring Bean으로 등록된 클래스의 매개변수가 선언된 생성자를 이용하여 객체 생성 -->
<!-- => bean 엘리먼트의 하위 엘리먼트를 사용하여 생성자 매개변수에 값을 전달하여 필드값으로 저장 -->
<!-- => Constructor Injection : 생성자를 이용하여 객체 필드 초기화 작업 실행 -->
<bean class="xyz.itwill05.di.Student" id="student2">
<!-- constructor-arg : Spring Bean으로 등록된 클래스의 생성자 매개변수에 값(객체)을
전달하기 위한 엘리먼트 -->
<!-- => constructor-arg 엘리먼트의 갯수만큼 매개변수가 선언된 생성자를 반드시 작성 -->
<!-- value 속성 : 매개변수에 전달하기 위한 값을 속성값으로 설정 -->
<!-- => Spring Bean으로 등록된 클래스가 객체로 생성될 때 필드에 전달값 저장 -->
<!-- => Value Injection : 객체의 필드에 값이 저장되도록 초기화 작업 실행 - 값 주입 -->
<!-- => 전달값은 기본적으로 문자열(String 객체)로 전달 - 매개변수의 자료형에 의해 자동 형변환 -->
<!-- => 매개변수의 자료형에 의해 자동 형변환될 경우 NumberFormatException 발생 가능 -->
<constructor-arg value="1000"/>
</bean>
<!-- constructor-arg 엘리먼트의 작성순서에 의해 매개변수에 값(객체)이 전달되어 객체 초기화 -->
<!--
<bean class="xyz.itwill05.di.Student" id="student3">
<constructor-arg value="2000"/>
<constructor-arg value="홍길동"/>
<constructor-arg value="abc@itwill.xyz"/>
</bean>
-->
<bean class="xyz.itwill05.di.Student" id="student3">
<!-- index 속성 : 생성자 매개변수에 값(객체)을 전달하기 위한 순서를 속성값으로 설정 -->
<!-- => index 속성값은 0부터 1씩 증가되는 정수값 사용 -->
<constructor-arg value="홍길동" index="1"/>
<constructor-arg value="abc@itwill.xyz" index="2"/>
<constructor-arg value="2000" index="0"/>
</bean>
<!-- 클래스의 기본 생성자를 이용하여 객체 생성 - 객체 필드에는 기본값 저장 -->
<!-- => 하위 엘리먼트 사용하여 Setter 메소드를 호출해 필드값 변경 - Setter Injection -->
<bean class="xyz.itwill05.di.Student" id="student4">
<!-- property : 객체의 Setter 메소드를 호출하여 필드값을 변경하는 엘리먼트 -->
<!-- name 속성 : 필드값을 변경하기 위한 필드명을 속성값으로 설정 - 자동 완성 기능 사용 가능 -->
<!-- => name 속성값으로 설정된 필드에 대한 Setter 메소드를 호출하여 필드값 변경 -->
<!-- => 필드에 대한 Setter 메소드가 없거나 잘못 선언된 경우 예외 발생 -->
<!-- value 속성 : 필드에 저장된 값을 속성값으로 설정 - 값 주입 -->
<property name="num" value="3000"/>
<property name="name" value="임꺽정"/>
<property name="email" value="xyz@itwill.xyz"/>
</bean>
<!-- 생성자(Constructor Injection)와 Setter 메소드(Setter Injection)를 같이 사용하여
객체 초기화 작업 가능 -->
<bean class="xyz.itwill05.di.Student" id="student5">
<constructor-arg value="4000"/>
<constructor-arg value="전우치"/>
<property name="email" value="opq@itwill.xyz"/>
</bean>
<!-- PropertyPlaceholderConfigurer 클래스 : Properties 파일을 제공받아 파일에 설정된
값을 Spring Bean Configuration File에서 사용할 수 있도록 제공하는 클래스 -->
<!-- => locations 필드에 Properties 파일의 경로를 전달하여 저장 -->
<!-- => Properties 파일에 의해 제공되는 값은 Spring Bean Configuration File에서 ${이름}으로 사용 -->
<!--
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="xyz/itwill05/di/student.properties"/>
</bean>
-->
<!-- Spring 5.2 이상에서는 PropertySourcesPlaceholderConfigurer 클래스를 사용하여
Properties 파일을 제공받아 Spring Bean Configuration File에서 사용할 수 있도록 변경 -->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations" value="xyz/itwill05/di/student.properties"/>
</bean>
<!-- Properties 파일에 의해 제공되는 값을 사용하여 객체 필드 초기화 작업 -->
<bean class="xyz.itwill05.di.Student" id="student6">
<property name="num" value="${num}"/>
<property name="name" value="${name}"/>
<property name="email" value="${email}"/>
</bean>
</beans>
참조변수 출력시 Student 클래스의 toString() 메소드 자동 호출
package xyz.itwill05.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StudentApp {
public static void main(String[] args) {
System.out.println("================== Spring Container 초기화 전 ==================");
ApplicationContext context=new ClassPathXmlApplicationContext("05-1_di.xml");
System.out.println("================== Spring Container 초기화 후 ==================");
Student student1=context.getBean("student1",Student.class);
//참조변수 출력시 Student 클래스의 toString() 메소드 자동 호출 - 객체의 필드값 확인
System.out.println(student1);
System.out.println("================================================================");
Student student2=context.getBean("student2",Student.class);
System.out.println(student2);
System.out.println("================================================================");
Student student3=context.getBean("student3",Student.class);
System.out.println(student3);
System.out.println("================================================================");
Student student4=context.getBean("student4",Student.class);
System.out.println(student4);
System.out.println("================================================================");
Student student5=context.getBean("student5",Student.class);
System.out.println(student5);
System.out.println("================================================================");
Student student6=context.getBean("student6",Student.class);
System.out.println(student6);
System.out.println("================================================================");
((ClassPathXmlApplicationContext)context).close();
}
}
#Student Properties
num = 5000
name = \uC77C\uC9C0\uB9E4
email = il@itwill.xyz
DI : Dependency Injection(의존성 주입)
스프링 컨테이너로 관리되는 Spring Bean을 객체 필드에 저장
package xyz.itwill05.di;
import java.util.List;
public interface StudentDAO {
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int num);
Student selectStudent(int num);
List<Student> selectStudentList();
}
DAO 클래스 : 저장매체(File, DBMS 등)에 대한 행 삽입, 변경, 삭제, 검색 기능을 제공하는 클래스
package xyz.itwill05.di;
import java.util.List;
public class StudentJdbcDAO implements StudentDAO {
public StudentJdbcDAO() {
System.out.println("### StudentJdbcDAO 클래스의 기본 생성자 호출 ###");
}
@Override
public int insertStudent(Student student) {
System.out.println("*** StudentJdbcDAO 클래스 insertStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int updateStudent(Student student) {
System.out.println("*** StudentJdbcDAO 클래스 updateStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int deleteStudent(int num) {
System.out.println("*** StudentJdbcDAO 클래스 deleteStudent(int num) 메소드 호출 ***");
return 0;
}
@Override
public Student selectStudent(int num) {
System.out.println("*** StudentJdbcDAO 클래스 selectStudent(int num) 메소드 호출 ***");
return null;
}
@Override
public List<Student> selectStudentList() {
System.out.println("*** StudentJdbcDAO 클래스 selectStudentList() 메소드 호출 ***");
return null;
}
}
package xyz.itwill05.di;
import java.util.List;
public class StudentMybatisDAO implements StudentDAO {
public StudentMybatisDAO() {
System.out.println("### StudentMybatisDAO 클래스의 기본 생성자 호출 ###");
}
@Override
public int insertStudent(Student student) {
System.out.println("*** StudentMybatisDAO 클래스 insertStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int updateStudent(Student student) {
System.out.println("*** StudentMybatisDAO 클래스 updateStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int deleteStudent(int num) {
System.out.println("*** StudentMybatisDAO 클래스 deleteStudent(int num) 메소드 호출 ***");
return 0;
}
@Override
public Student selectStudent(int num) {
System.out.println("*** StudentMybatisDAO 클래스 selectStudent(int num) 메소드 호출 ***");
return null;
}
@Override
public List<Student> selectStudentList() {
System.out.println("*** StudentMybatisDAO 클래스 selectStudentList() 메소드 호출 ***");
return null;
}
}
package xyz.itwill05.di;
import java.util.List;
public interface StudentService {
void addStudent(Student student);
void modifyStudent(Student student);
void removeStudent(int num);
Student getStudent(int num);
List<Student> getStudentList();
}
- Service 클래스 : 프로그램 실행에 필요한 데이타 처리 기능을 모듈화하여 제공하는 클래스 (컴퍼넌트)
- Service 클래스의 메소드는 다수의 DAO 클래스의 메소드를 호출하여 작성 (모듈화)
- DAO 클래스는 Service 클래스와 포함관계(의존관계)로 설정되도록 작성
- 포함관계 중에서 의존도가 높지 않은 관계 : 의존관계 (ex. TV와 리모콘)
- Service 클래스가 변경돼도 Service 클래스와 관계가 있는 클래스(모델 클래스)에 영향을 최소화하기 위해 반드시 인터페이스 상속받아 작성
- 결합도를 낮춰 유지보수의 효율성 증가
StudentJdbcDAO 객체를 저장하기 위한 필드
- StudentDAO 인터페이스를 상속받은 모든 DAO 클래스의 객체를 저장할 수 있는 필드
- StudentDAO 인터페이스를 상속받은 DAO 클래스의 객체를 저장해야만 의존관계 성립
- Service 클래스의 메소드에서 필드로 추상메소드를 호출하여 필드에 저장된 자식 객체의 메소드 호출
- 오버라이딩에 의한 다형성 : 결합도를 낮춰 유지보수의 효율성 증가
- DAO 클래스가 변경돼도 Service 클래스의 영향 최소화
private StudentDAO studentDAO;
package xyz.itwill05.di;
import java.util.List;
public class StudentServiceImpl implements StudentService {
//StudentJdbcDAO 객체를 저장하기 위한 필드
// => 필드에 StudentJdbcDAO 객체를 저장해야만 의존관계가 성립
// => StudentServiceImpl 클래스의 메소드에서 StudentJdbcDAO 객체의 메소드 호출 가능
//문제점)DAO 클래스가 변경될 경우 Service 클래스의 필드 및 메소드 변경
// => 결합도가 높아 유지보수의 효율성 감소
//해결법)DAO 클래스가 반드시 상속받아야 되는 인터페이스로 필드 선언
// => 필드에는 인터페이스를 상속받은 모든 DAO 클래스의 객체 저장 가능
//private StudentJdbcDAO studentJdbcDAO;
//StudentDAO 인터페이스를 상속받은 모든 DAO 클래스의 객체를 저장할 수 있는 필드
// => StudentDAO 인터페이스를 상속받은 DAO 클래스의 객체를 저장해야만 의존관계 성립
// => Service 클래스의 메소드에서 필드로 메소드를 호출하여 필드에 저장된 자식 객체의
//메소드 호출 - 오버라이딩에 의한 다형성 : 결합도를 낮춰 유지보수의 효율성 증가
// => DAO 클래스가 변경돼도 Service 클래스의 영향 최소화
private StudentDAO studentDAO;
public StudentServiceImpl() {
System.out.println("### StudentServiceImpl 클래스의 기본 생성자 호출 ###");
}
public StudentServiceImpl(StudentDAO studentDAO) {
super();
this.studentDAO = studentDAO;
System.out.println("### StudentServiceImpl 클래스의 매개변수가 선언된 생성자 호출 ###");
}
public StudentDAO getStudentDAO() {
return studentDAO;
}
public void setStudentDAO(StudentDAO studentDAO) {
this.studentDAO = studentDAO;
System.out.println("*** StudentServiceImpl 클래스 setStudentDAO(StudentDAO studentDAO) 메소드 호출 ***");
}
@Override
public void addStudent(Student student) {
System.out.println("*** StudentServiceImpl 클래스 addStudent(Student student) 메소드 호출 ***");
studentDAO.insertStudent(student);
}
@Override
public void modifyStudent(Student student) {
System.out.println("*** StudentServiceImpl 클래스 modifyStudent(Student student) 메소드 호출 ***");
studentDAO.updateStudent(student);
}
@Override
public void removeStudent(int num) {
System.out.println("*** StudentServiceImpl 클래스 removeStudent(int num) 메소드 호출 ***");
studentDAO.deleteStudent(num);
}
@Override
public Student getStudent(int num) {
System.out.println("*** StudentServiceImpl 클래스 getStudent(int num) 메소드 호출 ***");
return studentDAO.selectStudent(num);
}
@Override
public List<Student> getStudentList() {
System.out.println("*** StudentServiceImpl 클래스 getStudentList() 메소드 호출 ***");
return studentDAO.selectStudentList();
}
}
StudentDAO 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록
StudentService 인터페이스를 상속받아 자식클래스를 Spring Bean으로 등록
StudentServiceImpl 클래스의 매개변수가 선언된 생성자를 이용하여 객체 생성
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl">
<constructor-arg ref="studentJdbcDAO"/>
</bean>
StudentServiceImpl 클래스의 기본 생성자를 이용하여 객체를 생성
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl">
<property name="studentDAO" ref="studentJdbcDAO"/>
</bean>
기존에 사용하던 StudentJdbcDAO 클래스 대신 새롭게 작성한 StudentMybatisDAO 클래스로 의존관계를 변경하고자 할 경우 ref 속성값만 변경
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- StudentDAO 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
<bean class="xyz.itwill05.di.StudentJdbcDAO" id="studentJdbcDAO"/>
<bean class="xyz.itwill05.di.StudentMybatisDAO" id="studentMybatisDAO"/>
<!-- StudentService 인터페이스를 상속받아 자식클래스를 Spring Bean으로 등록 -->
<!-- => 클래스의 기본 생성자를 이용하여 객체 생성 - 객체 필드에는 기본값 저장 -->
<!-- 문제점)StudentServiceImpl 클래스로 생성된 객체의 필드에는 [null]이 저장되어 StudentServiceImpl
클래스의 메소드에서 StudentDAO 클래스의 메소드를 호출하면 NullPointerExcetion 발생 - 의존관계 미성립 -->
<!-- 해결법)StudentServiceImpl 클래스의 객체 필드에 StudentDAO 인터페이스를 상속받은
자식클래스의 객체가 저장되도록 설정 - 의존관계 성립 -->
<!-- <bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl"/> -->
<!-- StudentServiceImpl 클래스의 매개변수가 선언된 생성자를 이용하여 객체 생성 -->
<!-- => 생성자 매개변수에 StudentDAO 인터페이스를 상속받은 자식클래스의 객체를 전달하여
필드에 저장 - Constructor Injection -->
<!-- constructor-arg 엘리먼트를 사용하여 StudentServiceImpl 클래스의 객체 필드에
StudentDAO 인터페이스를 상속받은 자식클래스의 객체 저장 - 의존관계 성립 -->
<!-- ref 속성 : 스프링 컨테이너로 관리되는 Spring Bean의 식별자를 속성값으로 설정 -->
<!-- => 스프링 컨테이너로 관리되는 Spring Bean을 객체 필드에 저장 - 의존성 주입(DI : Dependency Injection) -->
<!--
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl">
<constructor-arg ref="studentJdbcDAO"/>
</bean>
-->
<!-- StudentServiceImpl 클래스의 기본 생성자를 이용하여 객체를 생성 -->
<!-- => Setter 메소드를 호출하여 StudentDAO 인터페이스를 상속받은 자식클래스의 객체를
필드에 저장 => Setter Injection -->
<!-- property 엘리먼트를 사용하여 StudentServiceImpl 클래스의 객체 필드에 StudentDAO
인터페이스를 상속받은 자식클래스의 객체 저장 - 의존관계 성립 -->
<!--
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl">
<property name="studentDAO" ref="studentJdbcDAO"/>
</bean>
-->
<!-- 기존에 사용하던 StudentJdbcDAO 클래스 대신 새롭게 작성한 StudentMybatisDAO 클래스로
의존관계를 변경하고자 할 경우 ref 속성값만 변경 -->
<!-- => 기존 클래스 대신 새로운 클래스로 바꿔도 관계가 설정된 클래스를 변경하지 않고
Spring Bean Configuration File만 수정해도 의존관계 변경 - 유지보수의 효율성 증가 -->
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentServiceImpl">
<property name="studentDAO" ref="studentMybatisDAO"/>
</bean>
</beans>
프로그램 실행에 필요한 데이타 처리 기능은 Service 클래스의 메소드를 호출하여 사용
StudentService service=context.getBean("studentServiceImpl", StudentService.class);
package xyz.itwill05.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StudentApp {
public static void main(String[] args) {
System.out.println("================== Spring Container 초기화 전 ==================");
ApplicationContext context=new ClassPathXmlApplicationContext("05-1_di.xml");
System.out.println("================== Spring Container 초기화 후 ==================");
Student student1=context.getBean("student1",Student.class);
//참조변수 출력시 Student 클래스의 toString() 메소드 자동 호출 - 객체의 필드값 확인
System.out.println(student1);
System.out.println("================================================================");
Student student2=context.getBean("student2",Student.class);
System.out.println(student2);
System.out.println("================================================================");
Student student3=context.getBean("student3",Student.class);
System.out.println(student3);
System.out.println("================================================================");
Student student4=context.getBean("student4",Student.class);
System.out.println(student4);
System.out.println("================================================================");
Student student5=context.getBean("student5",Student.class);
System.out.println(student5);
System.out.println("================================================================");
Student student6=context.getBean("student6",Student.class);
System.out.println(student6);
System.out.println("================================================================");
//프로그램 실행에 필요한 데이타 처리 기능은 Service 클래스의 메소드를 호출하여 사용
// => 스프링 컨테이너에게 Service 클래스의 객체를 제공받아 메소드 호출
//StudentServiceImpl service=context.getBean("studentServiceImpl", StudentServiceImpl.class);
//클래스로 참조변수를 생성하여 객체를 반환받아 저장하는 것보다는 인터페이스로 참조변수를
//생성하여 객체를 저장하는 것이 유지보수의 효율성 증가
// => 인터페이스로 반환받기 위한 객체의 형변환 가능
StudentService service=context.getBean("studentServiceImpl", StudentService.class);
service.addStudent(student1);
service.modifyStudent(student1);
service.removeStudent(1000);
service.getStudent(100);
service.getStudentList();
System.out.println("================================================================");
((ClassPathXmlApplicationContext)context).close();
}
}
package xyz.itwill05.di;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class CollectionBean {
private Set<String> nameSet;
private List<String> nameList;
//Collection 객체의 제네릭을 인터페이스로 설정하면 Collection 객체의 요소에는 인터페이스를
//상속받은 모든 자식클래스의 객체 저장 가능
private Set<Controller> controllerSet;
private List<Controller> controllerList;
private Map<String, Controller> controllerMap;
private Properties controllerProperties;
public CollectionBean() {
System.out.println("### CollectionBean 클래스의 기본 생성자 호출 ###");
}
public Set<String> getNameSet() {
return nameSet;
}
public void setNameSet(Set<String> nameSet) {
this.nameSet = nameSet;
}
public List<String> getNameList() {
return nameList;
}
public void setNameList(List<String> nameList) {
this.nameList = nameList;
}
public Set<Controller> getControllerSet() {
return controllerSet;
}
public void setControllerSet(Set<Controller> controllerSet) {
this.controllerSet = controllerSet;
}
public List<Controller> getControllerList() {
return controllerList;
}
public void setControllerList(List<Controller> controllerList) {
this.controllerList = controllerList;
}
public Map<String, Controller> getControllerMap() {
return controllerMap;
}
public void setControllerMap(Map<String, Controller> controllerMap) {
this.controllerMap = controllerMap;
}
public Properties getControllerProperties() {
return controllerProperties;
}
public void setControllerProperties(Properties controllerProperties) {
this.controllerProperties = controllerProperties;
}
}
package xyz.itwill05.di;
public interface Controller {
void handlRequest();
}
package xyz.itwill05.di;
public class LoginController implements Controller {
@Override
public void handlRequest() {
// TODO Auto-generated method stub
}
}
package xyz.itwill05.di;
public class LogoutController implements Controller {
@Override
public void handlRequest() {
// TODO Auto-generated method stub
}
}
package xyz.itwill05.di;
public class ListController implements Controller {
@Override
public void handlRequest() {
// TODO Auto-generated method stub
}
}
- set : Set 객체를 생성하여 필드에 저장하기 위한 엘리먼트 (순서X, 중복X)
- value : Collection 객체에 요소값을 추가하는 엘리먼트
- list : List 객체를 생성하여 필드에 저장하기 위한 엘리먼트 (순서O, 중복O)
- map : Map 객체를 생성하여 필드에 저장하기 위한 엘리먼트
- entry : Map 객체에 엔트리(Entry - Key & Value)를 추가하기 위한 엘리먼트
- key : 엔트리의 맵키(String)를 설정하기 위한 엘리먼트 (하위 엘리먼트 : value로 문자값으로 저장)
- ref : 엔트리의 맵값(Controller 객체)를 설정하기 위한 엘리먼트
- props : Properties 객체를 생성하여 필드에 저장하기 위한 엘리먼트
- 필드의 자료형 Map<String,String>인 경우 props 엘리먼트로 객체 필드에 Map 객체를 생성하여 저장 가능
- prop : Properties 객체에 엔트리를 추가하는 메소드
- 엘리먼트의 내용으로 엔트리에 저장될 값(문자열)을 설정
- key 속성 : 엔트리를 구분하기 위한 식별자(문자열)를 속성값으로 설정
<prop key="login">xyz.itwill05.di.LoginController</prop>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Controller 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
<bean class="xyz.itwill05.di.LoginController" id="loginController"/>
<bean class="xyz.itwill05.di.LogoutController" id="logoutController"/>
<bean class="xyz.itwill05.di.ListController" id="listController"/>
<bean class="xyz.itwill05.di.CollectionBean" id="collectionBean">
<property name="nameSet">
<!-- set : Set 객체를 생성하여 필드에 저장하기 위한 엘리먼트 -->
<set>
<!-- value : Collection 객체에 요소값을 추가하는 엘리먼트 -->
<value>홍길동</value>
<value>임꺽정</value>
<value>전우치</value>
<value>홍길동</value>
</set>
</property>
<property name="nameList">
<!-- list : List 객체를 생성하여 필드에 저장하기 위한 엘리먼트 -->
<list>
<value>홍길동</value>
<value>임꺽정</value>
<value>전우치</value>
<value>홍길동</value>
</list>
</property>
<property name="controllerSet">
<set>
<!-- Collection 객체의 요소로 Spring Bean으로 등록된 클래스의 객체를 추가하기 위한 엘리먼트 -->
<!-- bean 속성 : 요소로 추가될 Spring Bean의 식별자를 속성값으로 설정 - 자동 완성 기능 사용 가능 -->
<ref bean="loginController"/>
<ref bean="logoutController"/>
<ref bean="listController"/>
</set>
</property>
<property name="controllerList">
<list>
<ref bean="loginController"/>
<ref bean="logoutController"/>
<ref bean="listController"/>
</list>
</property>
<property name="controllerMap">
<!-- map : Map 객체를 생성하여 필드에 저장하기 위한 엘리먼트 -->
<map>
<!-- entry : Map 객체에 엔트리(Entry - Key & Value)를 추가하기 위한 엘리먼트 -->
<entry>
<!-- key : 엔트리의 맵키(String)를 설정하기 위한 엘리먼트 -->
<key>
<value>login</value>
</key>
<!-- ref : 엔트리의 맵값(Controller 객체)를 설정하기 위한 엘리먼트 -->
<ref bean="loginController"/>
</entry>
<entry>
<key>
<value>logout</value>
</key>
<ref bean="logoutController"/>
</entry>
<entry>
<key>
<value>list</value>
</key>
<ref bean="listController"/>
</entry>
</map>
</property>
<property name="controllerProperties">
<!-- props : Properties 객체를 생성하여 필드에 저장하기 위한 엘리먼트 -->
<!-- => 필드의 자료형 Map<String,String>인 경우 props 엘리먼트로 객체 필드에
Map 객체를 생성하여 저장 가능 -->
<props>
<!-- prop : Properties 객체에 엔트리를 추가하는 메소드 -->
<!-- => 엘리먼트의 내용으로 엔트리에 저장될 값(문자열)을 설정 -->
<!-- key 속성 : 엔트리를 구분하기 위한 식별자(문자열)를 속성값으로 설정 -->
<prop key="login">xyz.itwill05.di.LoginController</prop>
<prop key="logout">xyz.itwill05.di.LogoutController</prop>
<prop key="list">xyz.itwill05.di.ListController</prop>
</props>
</property>
</bean>
</beans>
package xyz.itwill05.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CollectionBeanApp {
public static void main(String[] args) {
System.out.println("================== Spring Container 초기화 전 ==================");
ApplicationContext context=new ClassPathXmlApplicationContext("05-2_collection.xml");
System.out.println("================== Spring Container 초기화 후 ==================");
CollectionBean bean=context.getBean("collectionBean",CollectionBean.class);
//CollectionBean 객체에 저장된 필드값을 반환받아 출력
// => Collection 객체의 toString() 메소드 자동 호출 - Collection 객체에 저장된 모든 요소값이 문자열로 반환
System.out.println("nameSet = "+bean.getNameSet());
System.out.println("nameList = "+bean.getNameList());
System.out.println("controllerSet = "+bean.getControllerSet());
System.out.println("controllerList = "+bean.getControllerList());
System.out.println("controllerMap = "+bean.getControllerMap());
System.out.println("controllerPropertes = "+bean.getControllerProperties());
System.out.println("================================================================");
((ClassPathXmlApplicationContext)context).close();
}
}
autowire : 스프링 컨테이너가 Spring Bean의 의존관계를 자동으로 구현되도록 설정하는 속성
- StudentService 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록
- StudentServiceImpl 클래스의 studentDAO 필드에 StudentDAO 인터페이스를 상속받은 자식클래스의 객체(Spring Bean)가 저장되도록 의존성 주입 (의존관계 성립)
- 의존성 주입을 하지 않으면 StudentServiceImpl 클래스의 메소드에서 StudentDAO 인터페이스를 상속받은 자식클래스의 메소드를 호출할 경우 NullPointerException 발생 (기본생성자 호출)
- property 엘리먼트를 사용하여 studentDAO 필드에 StudentDAO 인터페이스를 상속받은 자식클래스의 객체(Spring Bean)가 저장되도록 설정 (Setter Injection)
- autowire 속성: no(기본), byName, byType, constructor 중 하나를 속성값으로 설정
no 속성값 : 자동으로 의존관계를 구현하는 기능 미사용
byName 속성값 : Spring Bean으로 등록된 클래스의 필드명과 같은 이름의 식별자(beanName)로 선언된 Spring Bean를 제공받아 필드에 저장되도록 의존성 주입 (Setter Injection)
byType 속성값 : Spring Bean으로 등록된 클래스의 필드와 같은 자료형의 Spring Bean을 제공받아 필드에 저장되도록 의존성 주입 (Setter Injection)
constructor 속성값 : Spring Bean으로 등록된 클래스의 필드와 같은 자료형의 Spring Bean을 제공받아 필드에 저장되도록 의존성 주입 (Constructor Injection)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- StudentDAO 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
<bean class="xyz.itwill05.di.StudentJdbcDAO" id="studentJdbcDAO"/>
<!-- <bean class="xyz.itwill05.di.StudentJdbcDAO" id="studentDAO"/> -->
<bean class="xyz.itwill05.di.StudentMybatisDAO" id="studentMybatisDAO"/>
<!-- StudentService 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
<!-- => StudentServiceImpl 클래스의 studentDAO 필드에 StudentDAO 인터페이스를 상속받은
자식클래스의 객체(Spring Bean)가 저장되도록 의존성 주입 - 의존관계 성립 -->
<!-- => 의존성 주입을 하지 않으면 StudentServiceImpl 클래스의 메소드에서 StudentDAO
인터페이스를 상속받은 자식클래스의 메소드를 호출할 경우 NullPointerException 발생 -->
<!-- property 엘리먼트를 사용하여 studentDAO 필드에 StudentDAO 인터페이스를 상속받은 자식
클래스의 객체(Spring Bean)가 저장되도록 설정 - Setter Injection -->
<!--
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentService">
<property name="studentDAO" ref="studentJdbcDAO"/>
</bean>
-->
<!-- autowire 속성: no(기본), byName, byType, constructor 중 하나를 속성값으로 설정 -->
<!-- => 스프링 컨테이너가 Spring Bean의 의존관계를 자동으로 구현되도록 설정하는 속성 -->
<!-- no 속성값 : 자동으로 의존관계를 구현하는 기능 미사용 -->
<!--
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentService" autowire="no">
<property name="studentDAO" ref="studentJdbcDAO"/>
</bean>
-->
<!-- byName 속성값 : Spring Bean으로 등록된 클래스의 필드명과 같은 이름의 식별자(beanName)로
선언된 Spring Bean를 제공받아 필드에 저장되도록 의존성 주입 - Setter Injection -->
<!-- => 필드명과 같은 이름의 식별자(beanName)로 선언된 Spring Bean이 없는 경우 의존성 미주입 - NullPointerException 발생 -->
<!-- <bean class="xyz.itwill05.di.StudentServiceImpl" id="studentService" autowire="byName"/> -->
<!-- byType 속성값 : Spring Bean으로 등록된 클래스의 필드와 같은 자료형의 Spring Bean를
제공받아 필드에 저장되도록 의존성 주입 - Setter Injection -->
<!-- => 필드의 자료형이 인터페이스인 경우 인터페이스를 상속받은 자식클래스로 등록된
Spring Bean의 객체를 제공받아 필드에 저장되도록 의존성 주입 -->
<!-- => 필드와 같은 자료형의 Spring Bean이 2개 이상 등록된 경우 의존성 주입 실패 - NoUniqueBeanDefinitionException 발생 -->
<!-- <bean class="xyz.itwill05.di.StudentServiceImpl" id="studentService" autowire="byType"/> -->
<!-- constructor 속성값 : Spring Bean으로 등록된 클래스의 필드와 같은 자료형의 Spring Bean를
제공받아 필드에 저장되도록 의존성 주입 - Constructor Injection -->
<!-- => 필드의 자료형이 인터페이스인 경우 인터페이스를 상속받은 자식클래스로 등록된
Spring Bean의 객체를 제공받아 필드에 저장되도록 의존성 주입 -->
<!-- => 필드와 같은 자료형의 Spring Bean이 2개 이상 등록된 경우 기본 생성자로 객체 생성 - 의존성 미주입 -->
<bean class="xyz.itwill05.di.StudentServiceImpl" id="studentService" autowire="constructor"/>
</beans>
package xyz.itwill05.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AutoWireApp {
public static void main(String[] args) {
System.out.println("================== Spring Container 초기화 전 ==================");
ApplicationContext context=new ClassPathXmlApplicationContext("05-3_autowire.xml");
System.out.println("================== Spring Container 초기화 후 ==================");
StudentService service=context.getBean("studentService",StudentService.class);
service.addStudent(null);
System.out.println("================================================================");
((ClassPathXmlApplicationContext)context).close();
}
}
<context:component-scan base-package="xyz.itwill05.di"/>
: xyz.itwill05.di 에서 어노테이션을 찾아 객체로 만들겠다
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="xyz.itwill05.di"/>
</beans>
@Component : 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
@Repository : DAO 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
@Repository("studentDAO")
@Primary : 의존성을 주입하기 위한 우선권을 제공하기 위한 어노테이션
package xyz.itwill05.di;
import java.util.List;
import org.springframework.stereotype.Repository;
//@Component : 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
// => 클래스의 이름을 beanName으로 자동 설정 - 클래스의 이름에서 첫문자는 소문자로 변환
// => @Component 어노테이션의 value 속성을 사용하여 beanName 변경 가능 - 다른 속성이 없는 경우 속성값만 설정 가능
//@Component
//@Repository : DAO 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
// => 클래스의 이름을 beanName으로 자동 설정하지만 value 속성으로 beanName 변경 가능
//@Repository("studentDAO")
@Repository
//@Primary : 의존성을 주입하기 위한 우선권을 제공하기 위한 어노테이션
// => 동일 자료형의 클래스에 @Primary 어노테이션을 사용한 경우 의존성 주입 실패
//@Primary
public class AnnotationStudentJdbcDAO implements StudentDAO {
public AnnotationStudentJdbcDAO() {
System.out.println("### AnnotationStudentJdbcDAO 클래스의 기본 생성자 호출 ###");
}
@Override
public int insertStudent(Student student) {
System.out.println("*** AnnotationStudentJdbcDAO 클래스의 insertStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int updateStudent(Student student) {
System.out.println("*** AnnotationStudentJdbcDAO 클래스의 updateStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int deleteStudent(int num) {
System.out.println("*** AnnotationStudentJdbcDAO 클래스의 deleteStudent(int num) 메소드 호출 ***");
return 0;
}
@Override
public Student selectStudent(int num) {
System.out.println("*** AnnotationStudentJdbcDAO 클래스의 selectStudent(int num) 메소드 호출 ***");
return null;
}
@Override
public List<Student> selectStudentList() {
System.out.println("*** AnnotationStudentJdbcDAO 클래스의 selectStudentList() 메소드 호출 ***");
return null;
}
}
package xyz.itwill05.di;
import java.util.List;
import org.springframework.stereotype.Repository;
@Repository
public class AnnotationStudentMybatisDAO implements StudentDAO {
public AnnotationStudentMybatisDAO() {
System.out.println("### AnntationStudentMybatisDAO 클래스의 기본 생성자 호출 ###");
}
@Override
public int insertStudent(Student student) {
System.out.println("*** AnntationStudentMybatisDAO 클래스의 insertStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int updateStudent(Student student) {
System.out.println("*** AnntationStudentMybatisDAO 클래스의 updateStudent(Student student) 메소드 호출 ***");
return 0;
}
@Override
public int deleteStudent(int num) {
System.out.println("*** AnntationStudentMybatisDAO 클래스의 deleteStudent(int num) 메소드 호출 ***");
return 0;
}
@Override
public Student selectStudent(int num) {
System.out.println("*** AnntationStudentMybatisDAO 클래스의 selectStudent(int num) 메소드 호출 ***");
return null;
}
@Override
public List<Student> selectStudentList() {
System.out.println("*** AnntationStudentMybatisDAO 클래스의 selectStudentList() 메소드 호출 ***");
return null;
}
}
@Service : Service 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
@Autowired : 스프링 컨테이너로부터 Spring Bean를 제공받아 필드에 저장되도록 의존관계를 자동으로 구현하기 위한 어노테이션
- 해결법1) 필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재할 경우 필드에 저장될 Spring Bean의 식별자(beanName)를 필드명과 같은 이름으로 변경 (DAO클래스에서 작성)
@Repository("studentDAO")
- @Autowired 어노테이션은 필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재하는 경우 bean 엘리먼트에서 autowire 속성값을 [byName]으로 설정한 것과 같은 방법으로 의존성 주입
- 해결법2) 필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재할 경우 필드에 저장될 Spring Bean에 대한 클래스에 @Primary 어노테이션을 사용하여 작성 (DAO클래스에서 작성)
- 해결법3) 필드에 @Qualifier 어노테이션을 사용하여 의존성 주입을 위한 Spring Bean 지정 (service class에서 작성)
- @Primary 어노테이션과 @Qualifier 어노테이션이 같이 설정된 경우 @Qualifier 어노테이션으로 의존성 주입
- @Qualifier : 필드와 의존관계가 설정될 Spring Bean를 직접 지정하기 위한 어노테이션
- @Autowired 어노테이션에 종속된 어노테이션
- value 속성 : 의존성 주입을 위한 Spring Bean의 식별자(beanName)를 속성값으로 설정
- 다른 속성이 없는 경우 속성값만 설정 가능 (beanName은 클래스이름에서 첫문자만 소문자로 변경)
@Qualifier("annotationStudentJdbcDAO")
- 문제점 : 순환 참조(서로 참조)로 인해 메모리가 과도하게 쌓여 stackoverflow 현상이 일어남
package xyz.itwill05.di;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
//@Component("studentService")
//@Service : Service 클래스를 스프링 컨테이너가 관리할 수 있는 Spring Bean으로 등록하기 위한 어노테이션
// => 클래스의 이름을 beanName으로 자동 설정하지만 value 속성으로 beanName 변경 가능
@Service("studentService")
public class AnnotationStudentServiceImpl implements StudentService {
//@Autowired : 스프링 컨테이너로부터 Spring Bean를 제공받아 필드에 저장되도록 의존관계를
//자동으로 구현하기 위한 어노테이션
// => 의존성 주입을 위해 필드에 사용하는 어노테이션 - 선언된 필드마다 어노테이션 설정
// => bean 엘리먼트에서 autowire 속성값을 [byType]으로 설정한 것과 같은 방법으로 의존성 주입 - Setter Injection
// => Setter 메소드를 이용하여 의존관계를 설정하지만 Setter 메소드를 작성하지 않아도 의존성 주입
//문제점)필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재할 경우 의존성 주입 실패 - NoUniqueBeanDefinitionException 발생
//해결법-1)필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재할 경우 필드에 저장될
//Spring Bean의 식별자(beanName)를 필드명과 같은 이름으로 변경
// => @Autowired 어노테이션은 필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재하는
//경우 bean 엘리먼트에서 autowire 속성값을 [byName]으로 설정한 것과 같은 방법으로 의존성 주입
@Autowired
//해결법-2)필드의 자료형과 같은 자료형의 Spring Bean이 2개 이상 존재할 경우 필드에 저장될
//Spring Bean에 대한 클래스에 @Primary 어노테이션을 사용하여 작성
//해결법-3)필드에 @Qualifier 어노테이션을 사용하여 의존성 주입을 위한 Spring Bean 지정
// => @Primary 어노테이션과 @Qualifier 어노테이션이 같이 설정된 경우 @Qualifier 어노테이션으로 의존성 주입
//@Qualifier : 필드와 의존관계가 설정될 Spring Bean를 직접 지정하기 위한 어노테이션
// => @Autowired 어노테이션에 종속된 어노테이션
//value 속성 : 의존성 주입을 위한 Spring Bean의 식별자(beanName)를 속성값으로 설정
// => 다른 속성이 없는 경우 속성값만 설정 가능
//@Qualifier("annotationStudentJdbcDAO")
@Qualifier("anntationStudentMybatisDAO")
private StudentDAO studentDAO;
//@Autowired 어노테이션 대신 @Resource 어노테이션 또는 @Inject 어노테이션을 사용하여 의존성 주입 가능
// => @Autowired 어노테이션은 Spring Framework의 라이브러리로 제공하는 어노테이션이지만
//@Resource 어노테이션 또는 @Inject 어노테이션은 JDK 라이브러리로 제공하는 어노테이션
// => @Resource 어노테이션 또는 @Inject 어노테이션은 다른 Framework에서 사용 가능
//@Resource : bean 엘리먼트에서 autowire 속성값을 [byName]으로 설정한 것과 같은 방법으로 의존성 주입
//@Inject : bean 엘리먼트에서 autowire 속성값을 [byType]으로 설정한 것과 같은 방법으로 의존성 주입
public AnnotationStudentServiceImpl() {
System.out.println("### AnnotationStudentServiceImpl 클래스의 기본 생성자 호출 ###");
}
@Override
public void addStudent(Student student) {
System.out.println("*** AnnotationStudentServiceImpl 클래스 addStudent(Student student) 메소드 호출 ***");
studentDAO.insertStudent(student);
}
@Override
public void modifyStudent(Student student) {
System.out.println("*** AnnotationStudentServiceImpl 클래스 modifyStudent(Student student) 메소드 호출 ***");
studentDAO.updateStudent(student);
}
@Override
public void removeStudent(int num) {
System.out.println("*** AnnotationStudentServiceImpl 클래스 removeStudent(int num) 메소드 호출 ***");
studentDAO.deleteStudent(num);
}
@Override
public Student getStudent(int num) {
System.out.println("*** AnnotationStudentServiceImpl 클래스 getStudent(int num) 메소드 호출 ***");
return studentDAO.selectStudent(num);
}
@Override
public List<Student> getStudentList() {
System.out.println("*** AnnotationStudentServiceImpl 클래스 getStudentList() 메소드 호출 ***");
return studentDAO.selectStudentList();
}
}
package xyz.itwill05.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationStudentApp {
public static void main(String[] args) {
System.out.println("================== Spring Container 초기화 전 ==================");
ApplicationContext context=new ClassPathXmlApplicationContext("05-4_diAnnotation.xml");
System.out.println("================== Spring Container 초기화 후 ==================");
StudentService service=context.getBean("studentService",StudentService.class);
service.addStudent(null);
System.out.println("================================================================");
((ClassPathXmlApplicationContext)context).close();
}
}