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>
	<!-- Hello bean설정 -->
	<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메서드 호출하기
		
		Hello hello1=new Hello();
		System.out.println(hello1.getMessage());
		
		Hello hello2=new Hello();
		System.out.println(hello2.getMessage());
		
		System.out.println(hello1==hello2); //false
	}
}
  • 기존 java 방식으로 Model인 Hello 클래스의 메서드
  • 같은 클래스를 참조하는 변수라도 생성될 때마다 서로 다른 주소에 저장
public class HelloMain {

	public static void main(String[] args) {

		//스프링방식으로 hello메서드 호출하기
		//xml파일 가져오기..웹으로실행시 web.xml에 설정이 되어있으므로 필요없다
		
		ApplicationContext app1=new ClassPathXmlApplicationContext("helloContext.xml");
		
		//hello객체생성
		Hello h1=(Hello)app1.getBean("hello"); //방법1
		System.out.println(h1.getMessage());
		
		Hello h2=app1.getBean("hello", Hello.class); //방법2
		System.out.println(h2.getMessage());
		
		System.out.println(h1==h2); //true 생성주소 같다..스프링에서는 기본이 싱글톤
	}
}
  • 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;
	}

	//setter
	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">
		<!-- MyInfo는 생성자주입 -->
		<constructor-arg ref="my"/>
		<!-- 학교명은 setter주입 -->
		<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생성후 확인
		MyInfo my=(MyInfo)context.getBean("my");
		
		System.out.println(my.toString());
		System.out.println(my); //메서드가 하나뿐이라 메서드 선언 없어도 같은 작업 실행됨
		
		//Person
		Person per=context.getBean("person", Person.class);
		per.writeData();
	}
}
  • View에서 출력
/* 출력결과

MyInfo[name=민희, age=22, addr=강남구 역삼동 쌍용교육센터]
MyInfo[name=민희, age=22, addr=강남구 역삼동 쌍용교육센터]
**학생정보 출력**
학교명: 쌍용고등학교
학생명: 민희
나이: 22
주소: 강남구 역삼동 쌍용교육센터
*/

Annotation

  • @(annotation) 사용하여 간접적으로 bean 생성하는 방법
  • @Component : bean 생성 기능
  • @Autowired : 생성자 선언 기능(다른 클래스 멤버 값 참조 기능)
  • @Resource : @Autowired와 같지만 참조할 클래스가 두 개 이상일 경우 명확히 하나를 지정
public interface DaoInter {

	public void insertData(String str);
	public void deleteData(String num);
}
  • Model로서 사용할 인터페이스
@Component //자동으로 빈에 등록(id는 클래스명,단 첫글자만 소문자 즉 myDao가 id가됨)
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") //id가 logic이 된다
public class LogicController {

	@Autowired
	//정확한 빈의 아이디로 주입_모호성이 있는경우에는 @Resource(name="정확한이름")
	DaoInter daoInter;
	
	public LogicController(MyDao dao) {
		this.daoInter=dao;
	}
	
	//insert
	public void insert(String str) {
		daoInter.insertData(str);
	}
	
	//delete
	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) {
		// TODO Auto-generated method stub

		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();
}
  • Model을 인터페이스로 작성
@Component("kfruit")
public class KoreanFruit implements Fruit {

	@Override
	public void writeFruitName() {
		System.out.println("한국과일은 맛있다");
	}
}
  • 인터페이스를 implements한 클래스
@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에서 어노테이션으로 명확히 지정된 클래스 참조하여 호출 가능
profile
초보개발자

0개의 댓글