스프링 제공 기능
애플리케이션 개발 중 소스 코드 수정 해야하는 경우가 많이 발생한다.
하지만, 객체 간의 결합력이 높을수록 수정이 어려워지게 되며, 느슨할수록 수정 즉, 애플리케이션의 유지 보수가 쉬워진다.
객체 간의 결합력을 느슨하게 하기 위해서는 인터페이스 를 사용하여 자료형을 선언하고, 이를 구현한 클래스 객체를 외부에서 생성 및 조립(대입)할 수 있도록 구현하여 결합력을 느슨하게 만들 수 있다.
public class Program {
public static void main(String[] args) {
Exam exam = new NewLecExam();
// ExamConsole console = new InlineExamConsole(exam); // DI : ExamConsole interface를 구현한 다른 객체를 조립함에 따라 다른 기능을 구현한다. 이처럼 수동으로 코드를 수정하여 의존 주입을 해주는 것을 IoC 컨테이너에게 위임한다.
ExamConsole console = new GridExamConsole(exam);
console.print();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- 설정 파일 name 스페이스 -->
<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">
<!-- 어떤 클래스(class)를 어떤 이름(id)의 빈으로 만들것인지 지정-->
<!-- *반드시 class명을 명시할 때 패키지명까지 입력해줘야 함. -->
<!-- *반드시 의존 주입 전에 빈객체로 등록해야 IoC 컨테이너에서 인식이 가능 -->
<!-- Exam exam = new NewlecExam(); -->
<bean id="exam" class="spring.di.entity.NewLecExam"/>
<!-- ExamConsole console = new GridExamConsole(); -->
<bean id="console" class="spring.di.ui.InlineExamConsole">
<!-- console.setExam(exam); //DI-->
<!-- 의존 주입 코드-->
<!-- 실제 setExam()이라는 메서드를 호출할 때 set을 생략 후 첫자를 소문자로 바꿔준 뒤 메서드를 호출해준다.-->
<!-- 따라서, name = (setE)exam 이며, 매개변수의 타입이 기본형이면 value, 참조형이면 ref를 사용한다. -->
<property name="exam" ref="exam"></property>
</bean>
</beans>
<dependencies> ... </dependencies>에 spring context 라이브러리 의존 추가ApplicationContext context =
new ClassPathXmlApplicationContext("spring/di/order.xml");
// 이름(id) 값으로 가져오기 - 클래스 타입이 뭔지 모르기 때문에 casting 필수.
(class type)context.getBean("id 값");
// 클래스타입(class)로 가져오기
context.getBean(clazz.class);
<property name="kor" value="20" /> <property name="kor">
<value>10</value>
</property>
- 오류 발생
Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'exam' defined in class path resource
[spring/di/order.xml]: Invalid property 'kor' of bean class
[spring.di.entity.NewLecExam]: Bean property 'kor' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
public class NewLecExam
private int kor;
...
<bean id="exam" class="spring.di.entity.NewLecExam">
<property name="kor" value="10"/>
</bean>
- getter & setter 추가 시 정상 동작
public class NewLecExam
private int kor;
...
public int getKor(){
return this.kor;
}
public void setKor(int kor){
this.kor = kor;
}
<constructor-arg/> 태그를 사용하여 오버로딩된 생성자의 매개변수 값을 추가해줄 수 있다. <bean id="exam" class="spring.di.entity.NewLecExam">
<constructore-arg>
<name>"매개변수명"</name>
<index>"0부터 시작, 매개변수 순서 인덱스"</index>
<type>"동일한 매개변수 갯수의 타입만 다른 생성자가 2개 이상 오버로딩된 경우, 사용할 생성자의 매개변수 타입 명시." </type>
<value>"매개값"</value>
</constructor-arg>
</bean>
namespaces에 아래 코드 추가.
<beans ....
xmlns:p="http://www.springframework.org/schema/p" //추가
>
namespace 추가 후, 아래처럼 간결한 형태로 설정 가능.
<bean id="exam" class="spring.di.entity.NewLecExam" p:kor="10" p:eng="20" p:math="30" p:com="40">
namespace란?
<bean id="" class="java.util.ArrayList"></bean> <bean id="exams" class="java.util.ArrayList">
<constructor-arg>
<list>
<bean class="spring.di.entity.NewLecExam" p:kor="10" p:eng="10"/>
<ref bean="exam"/>
</list>
</constructor-arg>
</bean>
namespaces에 아래 코드 추가.
xmlns:util="http://www.springframework.org/schema/util"
<util:list id="exams" list-class="java.util.ArrayList">
<bean class="spring.di.entity.NewLecExam" p:kor="10" p:eng="10"></bean>
<ref bean="exam"/>
</util:list>