MVC Structure_Basics
M(Model)
- 사용자 요청 사항 처리 작업
- 편집, 처리하고자 하는 모든 데이터를 가지고 있으며, 작업 처리 결과 데이터를 반환
- DAO, DTO
V(View)
- Model의 데이터를 사용자에게 보여주기 위한 작업
C(Controller)
- 사용자의 요청 사항을 직접적으로 수용하고 파악
- 이에 해당하는 Model 데이터 호출
- View에 호출한 결과를 반환 (Model과 View 중간에서 상호작용)
MVC using XML_Beans
Exercise
package framework.di.test;
public class Hello {
String msg="오늘은 스프링 배우는날!!";
public String getMessage() {
return "Hello메서드 호출:"+msg;
}
}
- framework.di.test 패키지의 java 파일
- Model로서 필요한 데이터와 이를 처리할 메서드 소유
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean name="hello" class="framework.di.test.Hello"/>
</beans>
- Controller로서 Model의 데이터를 호출하여 View에 전달하기 위한 bean(xml) 형태로 변환
- Model인 Hello 클래스의 bean을 xml 형식으로 처리
- name(혹은 id)은 해당 bean의 참조명이며, class에 Model의 클래스 참조
public class HelloMain {
public static void main(String[] args) {
Hello hello1=new Hello();
System.out.println(hello1.getMessage());
Hello hello2=new Hello();
System.out.println(hello2.getMessage());
System.out.println(hello1==hello2);
}
}
- 기존 java 방식으로 Model인 Hello 클래스의 메서드
- 같은 클래스를 참조하는 변수라도 생성될 때마다 서로 다른 주소에 저장
public class HelloMain {
public static void main(String[] args) {
ApplicationContext app1=new ClassPathXmlApplicationContext("helloContext.xml");
Hello h1=(Hello)app1.getBean("hello");
System.out.println(h1.getMessage());
Hello h2=app1.getBean("hello", Hello.class);
System.out.println(h2.getMessage());
System.out.println(h1==h2);
}
}
- View로서 사용자에게 보여지기 위한 작업(출력)
- ApplicationContext 인터페이스의 ClassPathXmlApplicationContext() 메서드를 통해 xml 형식의 bean을 호출 (메서드의 인자 값으로 bean이 속한 xml 파일 입력)
- 호출하고자 하는 bean의 참조명을 getBean() 메서드의 인자 값에 넣음
- getBean()의 인자가 하나일 때는 참조하는 객체의 자료형(클래스)으로 형 변환하고, 인자가 둘일 때는 두 번째 인자로써 참조 객체 자료형(클래스)를 .class 형태로 선언
- bean으로 생성된 객체는 모두 같은 주소를 공유
Model Created As a Interface
- Model이 인터페이스로 선언될 경우 이를 implements 받은 클래스를 Controller에서 bean으로 변환
Constructor & Setter Injection
- Model에서 명시적 생성자 및 setter를 선언하여, 데이터를 처리할 경우 값을 주입하는 방법
public class MyInfo {
String name;
int age;
String addr;
public MyInfo(String name,int age,String addr) {
super();
this.name=name;
this.age=age;
this.addr=addr;
}
@Override
public String toString() {
return "MyInfo[name="+name+", age="+age+", addr="+addr+"]";
}
}
- MyInfo 클래스의 명시적 생성자로 변수를 주입 받고자 하는 java Model
public class Person {
String schoolName;
MyInfo info;
public Person(MyInfo info) {
this.info=info;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public void writeData() {
System.out.println("**학생정보 출력**");
System.out.println("학교명: "+schoolName);
System.out.println("학생명: "+info.name);
System.out.println("나이: "+info.age);
System.out.println("주소: "+info.addr);
}
}
- 다른 클래스(위의 MyInfo)의 멤버 변수를 가져오기 위해 자료형을 클래스로 선언 후 변수화
- 나머지 변수는 setter를 선언하여 setter로 주입 받고자 하는 java Model (getter로 출력하고자 하면 getter도 선언 가능)
<beans>
<bean id="my" class="spring.di.ex2.MyInfo">
<constructor-arg value="민희"/>
<constructor-arg value="22"/>
<constructor-arg>
<value>강남구 역삼동 쌍용교육센터</value>
</constructor-arg>
</bean>
<bean id="person" class="spring.di.ex2.Person">
<constructor-arg ref="my"/>
<property name="schoolName" value="쌍용고등학교"/>
</bean>
</beans>
- Controller에서 Model을 xml 형식의 bean으로 변환
- 이 과정에서 생성자 및 setter로 주입 받고자 하는 값 주입 가능
- <constructor-arg>태그의 value 속성으로 생성자 주입 (value 속성 대신 태그 내부의 <value>태그의 값으로 대체 가능)
- 다른 클래스의 멤버 값을 그대로 참조하고자 하는 경우 <constructor-arg>태그의 ref 속성(bean 참조명 사용)으로 참조 가능
- <property>태그로 setter 주입 가능하며, 주입하고자 하는 변수명을 name 속성에, 값을 value에 입력
public class Ex2Main {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("appContext2.xml");
MyInfo my=(MyInfo)context.getBean("my");
System.out.println(my.toString());
System.out.println(my);
Person per=context.getBean("person", Person.class);
per.writeData();
}
}
Annotation
- @(annotation) 사용하여 간접적으로 bean 생성하는 방법
- @Component : bean 생성 기능
- @Autowired : 생성자 선언 기능(다른 클래스 멤버 값 참조 기능)
- @Resource : @Autowired와 같지만 참조할 클래스가 두 개 이상일 경우 명확히 하나를 지정
public interface DaoInter {
public void insertData(String str);
public void deleteData(String num);
}
@Component
public class MyDao implements DaoInter {
@Override
public void insertData(String str) {
System.out.println(str+"_str데이터를 db에 추가완료");
}
@Override
public void deleteData(String num) {
System.out.println(num+"_num에 해당하는 데이터 삭제완료");
}
}
- @Component 어노테이션을 사용하여 xml 파일의 <bean>생성과 같은 효과
- 생성된 bean의 참조명은 클래스명의 첫 글자를 소문자로 변환한 것과 같음
@Component("logic")
public class LogicController {
@Autowired
DaoInter daoInter;
public LogicController(MyDao dao) {
this.daoInter=dao;
}
public void insert(String str) {
daoInter.insertData(str);
}
public void delete(String num) {
daoInter.deleteData(num);
}
}
- @Component 어노테이션의 인자 값으로 bean의 참조명 변경 가능
- @Autowired 어노테이션으로 <constructor arg ref=””>와 같이 다른 클래스의 멤버 값 그대로 참조
<beans xmlns:context="http://www.springframework.org/schema/context">
<context:component-scan base-package="spring.anno.*"/>
</beans>
- xmlns:context 속성 생성
- <context:component-scan base-package="">태그로 @Component 어노테이션으로 생성한 bean을 참조하고자 하는 패키지 지정 (,로 일일이 지정도 가능하며 *와일드카드도 사용 가능)
public class LogicMain {
public static void main(String[] args) {
ApplicationContext anno1=new ClassPathXmlApplicationContext("annoContext4.xml");
LogicController logic1=(LogicController)anno1.getBean("logic");
logic1.insert("어노테이션 연습");
logic1.delete("1");
}
}
- ClassPathXmlApplicationContext() 메서드의 인자 값으로는 @Component 어노테이션을 스캔하고자 하는 명령어를 실행한 파일을 입력
- 이외에는 bean 선언한 것과 같이 실행
Duplicated Component Annotation_@Resource
public interface Fruit {
public void writeFruitName();
}
@Component("kfruit")
public class KoreanFruit implements Fruit {
@Override
public void writeFruitName() {
System.out.println("한국과일은 맛있다");
}
}
@Component("tfruit")
public class ThaiFruit implements Fruit {
@Override
public void writeFruitName() {
System.out.println("태국하면 망고");
}
}
- 같은 인터페이스를 implements한 다른 클래스
@Component
public class MyFruit {
@Resource(name = "tfruit")
Fruit fruit;
public void writeFruit() {
System.out.println("내가 좋아하는 과일은 **");
fruit.writeFruitName();
}
}
- Controller에서 @Autowired 어노테이션으로 다른 생성자를 생성하려면 두 개의 클래스 중 어떤 것을 참조해야 하는지 불분명해지므로 오류 발생
- 이러한 경우는 @Resource(name=””) 어노테이션으로 참조할 생성자를 명확히 지정 필요
public class Ex5Main {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("annoContext4.xml");
MyFruit myfruit=context.getBean("myFruit", MyFruit.class);
myfruit.writeFruit();
}
}
- View에서는 Controller에서 어노테이션으로 명확히 지정된 클래스 참조하여 호출 가능