반응형
SMALL

클래스

1. 객체란?

객체 : 쉽게 말해 덩어리. 속성과 동작으로 구성. 사람이 객체라고 치면, 사람은 이름이라는 속성이 있고, 걷다 등의 동작이 가능하다. 있다.

이러한 속성과 동작을 각각 필드(field)와 메소드(method)라고 부른다.

 

이러한 객체로 소프트웨어를 설계하면 객체지향 프로그래밍이 된다.

특징은 캡슐화, 상속, 다형성이 있음.

 

- 캡슐화 : 객체의 필드(=데이터)와 메소드(=동작)를 하나로 묶어서 내부를 감추면 외부의 객체는 알 수 없고 객체가 노출하는 필드와 메소드만 사용 가능하다. 이러면 외부에서 잘못사용해도 객체가 망가질 일이 없음. 

- 상속 : 부모와 자식으로 역할을 부여해서 자식은 부모의 것을 사용가능하다. 단, 부모는 자식꺼를 사용할 수 없음. 코드를 재사용할 수 있기 때문에 효율적임. 그리고 부모를 수정하면 그 아래 자식들이 자동으로 수정된 걸 쓰기 때문에 편함.

- 다형성 :  사용방법은 동일하지만 실행결과가 다양하게 나온다는 뜻. 객체를 바꾸면 프로그램의 실행 결과가 다르게 나올 수 있다.

 

 

2. 인스턴스

 클래스로부터 생성된 객체를 해당 클래스의 인스턴스(instance)라고 부른다. 클래스로부터 객체를 만드는 과정을 인스턴스화라고 함. 동일한 클래스로부터 여러 개의 인스턴스를 만들 수 있는데, 동일한 설계도로 여러대의 자동차를 만드는 것과 같다.

 

클래스 선언은 객체 생성을 위한 설계도를 작성하는 것과 같다.

 

 이 설계도(클래스) 접근 권한을 어떻게 할 것인지는 클래스 앞에 접근권한자를 붙여서 판단한다.

 

[클래스의 접근제한자]

public - 전부 공개(같은 패키지, 다른 패키지 전부 가능)

(default) - 같은 패키지 ㅇㅋ, 다른패키지는 안됨.

 

3. new 클래스()

객체 생성 연산자이다. 객체를 만드는데, 걔 이름이 이거라고 변수에 담아준다.

Student s1 = new Student();
//앞에 있는 Student와 뒤에 있는 Student는 같다.

Student라는 class가 있는데 그걸 new로 객체화해준다. 단, s1이라는 이름에 담아서.

이렇게 되면 인스턴스화 되어서 인스턴스가 생성되었으므로 Student 라는 클래스 안에 있는 애들을 s1 이름으로 불러다 쓸 수 있다.

 

1번 Student 클래스

//Student.java
public class Student{

}

2번 StudentExample 클래스

//StudentExample.java

public class StudentExample {

	public static void main(String[] args) {
		
		Student s1 = new Student();
		System.out.println("s1 변수가 Student 객체를 참조합니다." + s1);
		
		Student s2 = new Student();
		System.out.println("s2 변수가 또다른 Student 객체를 참조합니다.");
	}
}

총 2가지의 클래스가 있는데 클래스는 Student 처럼 실행은 못하지만 다른 클래스가 사용할 수 있도록 라이브러리 역할을 하는 클래스가 있고, StudentExample  처럼 main()메소드를 가지고 있어 실행 가능한 클래스가 있다.

 

4. 클래스 구성 멤버(필드, 생성자, 메소드)

public class 요소 {
	//--------- 필드 선언 ------------
	String company = "현대자동차";
	String 문자1;
	String 문자2;
	Boolean 불린;
	int 숫자;
	//--------- 아이템 생성 끝 ------------
	
	//-------- 여러개의 생성자 선언 ------------
	/*왜? 생성자가 있어야 쓸 수 있는데(조합 어떻게 갖다씀?)
	순서에 따라서 뭘 갖다쓸지 모르니까.*/

	//첫번 째 생성자
	public 요소(){}
	
	//두번 째 생성자
	요소(String company, int 숫자){
		this.company = company;
		this.숫자 = 숫자; //야 숫자 좀 받아줘
	}
	
	//3번 째 생성자
	요소(String company, String 문자2, Boolean 불린){
		this.company = company;
		this.문자2 = 문자2;
		this.불린 = 불린;
	}
}

main()이 없는 라이브러리형 클래스의 경우, main()이 선언된 실행 클래스에서 가져가기 위해 작업이 필요하다.

 

1) 필드는 변수 선언과 비슷하다. 쉽게 말해서 값 담는 그릇임.

java는 javascript와 다르게 변수 타입(형)이 굉장히 중요하기 때문에 필드에 알맞는 형(그릇의 재질처럼)을 부여해준다.

 

이 필드가 외부에서 마음대로 값을 읽고 변경하면 무결성이 깨지므로, getter/setter를 사용해서 들어갔다가 나오는 통로를 만들어준다.

 

2) 생성자는 쉽게 말해 그릇의 묶음이다.

필드가 값을 담는 그릇이라 다양한 재질(String, Boolean 등)이 선언되어 있는데 main()이 있는 실행클래스에서 뭘 갖다쓸지 모른다. 이 때 생성자를 호출하면 비어있는 껍데기를 템플릿처럼 가져와서 초기화할 수 있음.

 

위에서는 main()을 가진 실행 클래스가 company와 숫자 묶음을 호출하면 두번째 생성자를 호출할 것이고, company와 문자, 불린 묶음을 호출하면 세번째 생성자를 호출할 것이다. (첫번째꺼는 기본 생성자로 값이 들어있는 company만 가능)

 

나는 라이브러리형 클래스를 s1으로도 가져오고, 또 s2로도 가져오고 해서 템플릿을 다양하게 가져와서 복사해서 쓸꺼다. 그러면 한개 이상의 생성자를 쓴다면 해당 묶음의 재질(형)에 따라서 다양하게 활용 가능하다. 물론 캡슐화도 가능!

 

=> 이렇게 매개변수를 달리하는 생성자를 여러개 선언하는 것을 생성자 오버로딩이라고 한다.

 

중복된 생성자의 경우, this로 묶어서 사용 가능.

	//다른거 불러와
	Car(String model){
    	this(model, "은색", 250);
	}
	
	//불러와지는 생성자
	Car(String model, String color, int maxSpeed){
		this.model = model;
		this.color= color;
		this.maxSpeed = maxSpeed;
	}
}

 

 

3) 메소드는 객체의 동작이다.

public class Calculator {

	void powerOn() {
		System.out.println("전원을 켭니다");
	};
	
	void powerOff() {
		System.out.println("전원을 끕니다");
	}

	int plus(int x, int y) {
		int result = x + y;
		return result;
	}
    
    double plus(double x, double y) {
        double result = x + y;
        return result;
	}
}
public class CalculatorExample {
	
	public static void main(String[] args) {
		Calculator myCalc = new Calculator();
		
		myCalc.powerOn(); //실행됨
		
		int result = myCalc.plus(3,5); 
		System.out.println(result); //실행하고 찍음
	}
}

 

라이브러리 클래스인 Calculator에는 powerOn, powerOff, plus 와 같은 메소드가 있다. 

return 해서 결과값을 전달하거나, 아니면 리턴값이 없는 경우 void를 선언해서 동작만 한다.

뱉는거 아니면 움직이기만 하는거임.

 

라이브러리 클래스에서 powerOn() 이라는 클래스를 void로 선언했다면 그 동작을 main()이 선언된 실행 클래스에서 가져다 썼을 때 리턴값은 없지만 powerOn 안에 선언된 행동은 한다.(sysout을 뱉는다.)

 

return 하면 종료의 의미이다. 뒤에 리턴값이 있다면 멈추고 값을 뱉어내는 것.

 

만약 plus를 부를 때 값을 double 값을 넣고 호출하면 double plus 에 있는 값이 호출된다.

=> 매소드 이름은 같은데 매개변수를 달리하는 메소드를 여러개 선언하는 것을 메소드 오버로딩이라고 한다.

 

4.) 정적 멤버(static)

필드(그릇)과 메소드(동작)은 기본적으로 객체를 생성해야만 사용할 수 있지만, 그냥 객체 없이도 고정적으로 사용할 수 있는 정적 멤버를 만들 수 있다.

 

즉, new 하지 않아도 갖다쓸 수 있음. 정적 필드와 정적 메소드가 생길 수 있다.

 

public class Calculator {

	static double PI = 3.141592; //파이는 변경될일 없는 값이라 정적으로 선언
    
    static plus(int x, int y){
    	~~~
    }
}

 

이렇게 정적인거 갖다쓰는 경우엔 아래와 같다.

double result = 10 * 10 * Calculator.PI;
int result2 = Calculator.plus(10,5);

 

 

다만 이건 다른게, 객체생성을 하는 new()로 만든 인스턴스 필드와 인스턴스 메소드를 사용할 수 없다. 즉, static 한 애에게 다른 멤버도 추가해주거나 변경해주고 싶은 경우 new()로 인스턴스로 복사해서 그걸 써야하는 것.

 

참고로 main()함수도 static이 붙은 정적 메소드이므로, 객체 생성 없이 인스턴스 필드와 인스턴스 메소드 사용이 불가하므로 객체 생성 후에 갖다써야 한다.

 

5) 값 변경 불가할 땐 final 필드와 상수

final이 붙으면 값 변경 못한다고 보면 된다. static 붙으면 불변의 다 갖다쓸 수 있는 값, 즉, 상수가 되는거임.

 

 

6) 필드, 생성자, 메소드의 접근제한자

[클래스의 접근제한자]

public - 전부 공개(같은 패키지, 다른 패키지 전부 가능)

(default) - 같은 패키지 ㅇㅋ, 다른패키지는 안됨.

 

클래스는 이 두개만 되지만 그 내부의 필드, 생성자, 메소드는 몇개 더 사용 가능하다.

 


[필드, 생성자, 메소드의 접근제한자]

public - 전부 공개(같은 패키지, 다른 패키지 전부 가능)

protected - 같은 패키지이거나, 자식 객체만 사용 가능

(default) - 같은 패키지 ㅇㅋ, 다른패키지는 안됨.

private - 현재 클래스 내부에서만 사용 가능.

 

 

7) 싱글톤 패턴

애플리케이션 전체에서 단 한개의 객체만을 생성해서 사용하는 것. (=private로 생성자 접근제한해서 외부에서 new 못하게 막음) 객체 얻는 것은 getInstance() 메소드 호출로만 가능하다.

 


상속

프로그램에서는 상속은 자식이 부모를 선택한다.

public class 자식클래스 extends 부모클래스 {

}

 

부모클래스는 여러개일 수 없다. 단, 각 자식클래스는 동일한 부모클래스를 상속할 수 있다.

 

자식클래스 변수 = new 자식클래스();

부모 없는 자식 없듯이 이렇게 자식 객체를 생성하면 부모가 자동으로 생성된다. 즉, extends 를 해놓은 부모클래스는 객체 생성 시 함께 생성되는 거다.(물론 눈에 보이지는 않지만)

 

만약 plus를 부를 때 값을 double 값을 넣고 호출하면 double plus 에 있는 값이 호출된다.
=> 매소드 이름은 같은데 매개변수를 달리하는 메소드를 여러개 선언하는 것을 메소드 오버로딩이라고 한다.

 

위에서 설명한 이 메소드 오버로딩을 자식이 부모한테 쓸 수 있다.

즉, 부모한테 상속받아 가져온 것을 자기가 재정의해서 입맛대로 사용하는 것.

단, Override 라는 어노테이션을 붙여준다.

 

public class Calculator {

	public double areaCircle(double r){
    	Sysyem.out.println("Calculator 객체 안의 areaCircle 입니다");
        return 3.14159 * r * r;
}
public class Computer extends Calculator {

	@Override
	public double areaCircle(double r){
    	Sysyem.out.println("Calculator 객체 안의 areaCircle메소드를 오버라이딩");
        return Math.PI * r * r;
}
public class ComputerExample {
	public static void main(String[] args) {
    
    	int r = 10; //원의 반지름
        
      //그냥 기본적인 부모 메소드의 값
      Calculator calculator = new Calculator();
      System.out.println(calculator.areaCircle(r)); //314.159
      
      //자식이 갖다가 오버라이딩 해서 쓴 메소드 값
      Computer computer = new Computer();
      System.out.println(computer.areaCircle(r)); //314.15926535...  
	}
}

 

이렇게 나온다는 것!

 

 

final

동일하게 값을 변경 못하므로 클래스에 붙으면 상속이 불가하고, 메소드에 붙으면 오버라이딩을 못한다.

 

타입 변환

자식은 부모의 특징과 기능을 상속받았기 때문에 부모와 동일한 취급을 받을 수 있다. 즉, 자동으로 타입이 변환된다.

물론 부모걸로 자동 타입이 변환되면 부모클래스의 필드와 메소드만 접근 가능하다.

 

하지만 반대로 부모는 자식 타입으로 자동변환 되지 않는다. 이 경우 casting 연산자로 강제 타입 변환을 한다.

 

Parent parent = new Child(); //자동 타입 변환
Child child = (Child) parent; //강제 타입 변환

 

추상클래스(abstract)

새, 곤충, 물고기 클래스가 각각 있는데 공통되는 부분이 있어서 그걸 따로 묶고싶다. 그러면 이걸 추상클래스로 만들어서 상속시킨다.

public absract class Phone {
	void trunOn(){ //핸드폰들은 공통적으로 켜는 기능을 가짐
    	...
    }	
}

 

 

봉인된(Sealed) 클래스

Java15 부터 무분별한 자식 클래스 생성을 방지하기 위해서 봉인된(Sealed) 클래스가 도입되었다.

 

 

반응형
LIST
반응형
SMALL

스프링 프레임워크 (Spring Framework)

🍀 스프링(Spring) 이란?

자바 엔터프라이즈 개발을 편하게 해주는 오픈 소스 경량급 애플리케이션 프레임워크

- JAVA로 다양한 어플리케이션을 만들기 위해 개발을 더 쉽게 할 수 있도록 도와주는 프레임워크

- 동적인 웹 사이트를 개발하기 위한 여러 가지 서비스를 제공(jsp, MyBatis, JPA 등등)

- 전자정부 표준 프레임워크의 기반 기술로서 쓰이고 있다.

- 중복코드 사용률을 줄이고 비지니스 로직을 더 간단하게 해주며, 오픈소스를 좀 더 효율적으로 가져다 쓸 수 있음.

 

🍀 스프링의 특징

˙ 경량 컨테이너로서 자바 객체를 직접 관리한다.

˙ POJO(Plain Old Java Object) 방식의 프레임워크

    - POJO : 단순하고 가벼운 자바 객체(우리가 자바에서 개발하는 지극히 평범한 객체)

˙ IoC(Inversion of Control; 제어 반전) 지원

    - 필요에 따라 컨트롤의 제어권을 사용자가 갖지 않고 스프링에서 사용자의 코드를 호출

˙ DI(Dependency injection; 의존성 주입)를 통한 객체 간의 관계 구성

˙  AOP(Aspect-Oriented Programming; 관점 지향 프로그래밍) 지원

˙ 영속성과 관련한 다양한 서비스 지원

    - iBATIS, 하이버네이트 등 데이터베이스 처리 라이브러리와 연결할 수 있는 인터페이스 제공

˙  확장성이 높다.

    - 수많은 라이브러리가 스프링에서 지원되고 있기 때문에 사용에도 라이브러리를 별도로 분리하기도 용이하다.

 

🍀 스프링의 개발을 더 쉽게 해주는 기술들

1.  POJO(Plain Old Java Object) 방식

- POJO는 Java EE를 사용하면서 해당 플랫폼에 종속되어 있는 무거운 객체들을 만드는 것에 반발하여 나타난 용어이다.
- 별도의 프레임 워크 없이 Java EE를 사용할 때에 비해 인터페이스를 직접 구현하거나 상속받을 필요가 없어 기존 라이브러리를 지원하기 용이하고, 객체가 가볍다.
- 즉, getter/setter를 가진 단순한 자바 오브젝트를 말한다.

기존에는 프레임워크가 너무 무겁고 내용도 방대했다. 이러한 니즈를 충족하기 위해 경량 프레임워크인 스프링이 등장했다. 기존에 Java EE의 경우 미리 설계되어있는 인터페이스나 클래스를 상속받아서 무거운 객체들을 만들어야만 했는데, Spring은 일반적인 java 코드만으로 객체를 구성할 수 있게 된다. 따라서 더 유연하고 가볍게, 생산성을 높이며 프로그래밍이 가능해진다.

 

▼ JAVA EE란?

더보기

JAVA EE는 엔터프라이즈 에디션의 자바 플랫폼이다.

  • 자바 플랫폼 Java SE  (Standard Edition)
  • 자바 플랫폼 Java EE  (Enterprise Edtion)
  • 자바 플랫폼 Java ME (Micro Edtion)
  • Java FX 

모든 자바 플랫폼들은 자바 가상 머신(JVM)과 API로 구성되어 있다. JVM이 어플리케이션을 동작시키기 위한 프로그램이고 API는 개발에 필요한 함수들을 패키지로 묶어서 배포한다.

기본은 JAVA SE가 스탠다드라는 이름 답게 흔히 많이 쓰는 java.lang.*, java.io.*, java.util.* 등등 java 프로그래밍 언어를 배울때 사용하는 대부분의 패키지를 포함한다.

 

그렇다면 JAVA EE는 뭘까? JAVA SE 위에 구축된 버전으로 대규모, 다계층, 확장 가능한 특징이 있으며 대규모일 때 안정적이고 안전한 네트워크 애플리케이션을 개발 및 실행하기 위한 API를 추가로 포함한다. JAVA EE가 servlet, JSON, REST API, 웹소켓 등을 지원한다.

 

근데 이를 대규모로 지원하려다보니 용량도 크고 포함한 패키지가 많아서 속도가 느려지기도 한다는 말이다.


 

2. IoC(Inversion of Control, 제어 반전)

Spring에 가장 핵심적인 기능. 한마디로 알아서 해주는 비서가 하나 생겼다.

개발자는 JAVA 코딩시 new 연산자, 인터페이스 호출, 데이터 클래스 호출 방식으로 객체를 생성하고 소멸시킨다.

IoC란 인스턴스 (객체)의 생성부터 소멸까지 객체 생명주기 관리를 개발자가 하는게 아닌 스피링(컨테이너)가 대신 해주는 것을 말한다.

IoC는 개발자가 실수할 수 있는 생명주기 관리를 대신 해준다. 프로젝트 규모가 커질수록 객체와 자원을 이용하는 방법이 더 복잡해져 코드가 꼬일 수 있는데 이를 Spring의 IoC가 대신 자동 관리해준다.

ex) Spring IoC Container 에 Bean으로 등록된 것들을 의존성 주입하기 위해 어노테이션 @Autowired를 사용한다.

단, 제어권은 개발자가 아닌 IoC에게 있으며 IoC가 개발자의 코드를 호출하여 그 코드로 생명주기를 제어한다.

 

3. DI(Dependency Injection, 의존성 주입)

프로그래밍에서 구성요소 간의 의존 관계가 소스코드 내부가 아닌 외부의 설정파일을 통해 정의되는 방식이다.
코드 재사용을 높여 소스코드를 다양한 곳에 사용할 수 있으며 모듈간의 결합도도 낮출 수 있다.

쉽게 말하자면 게임 캐릭터라는 하나의 객체가 존재하는데, 그 객체를 더 잘 이용하기 위해서 무기, 방패 등 아이템을 가져와 결합시키는 것이다. 이 객체는 무기와 방패를 뺐다 꼈다 자유자재로 할 수 있으며 아이템을 갈아끼우는데 어떤 상황에 구애받지도 않는다.(그리고 그 아이템을 갈아끼우는걸 IoC Container가 해준다.)

JAVA에서 데이터를 저장하고 가져오는 기능을 외부의 Oracle Database를 사용할 수도 있고, JDBC, iBatis, JPA 등 다른 프레임 워크를 이용해 짤 수도 있다. 이때 Spring을 이용하면 그때마다 필요한 부분을 뺐다 꼈다 하면서 적절한 상황에 필요한 기능을 해낼 수 있다.

 

▼ Spring은 DI를 지원하는 조립기다. 의존성 주입을 지원하는 방식은 크게 3가지이다.

 

더보기

1) 생성자 주입

public class Car {
    private Tire tire;

    public Car(Tire tire) {
        this.tire = tire;
    }
}

생성자 주입은 위에서 보았던 예시처럼 생성자를 사용해서 외부에서 주입을 해주는 것.

 

2) setter 주입

public class Car {
    private Tire tire;

    public Tire getTire() {
        return tire;
    }

    public void setTire(Tire tire) {
        this.tire = tire;
    }
}



public class Client {
    public static void main(String[] args) {
        Tire tire = new KoreaTire();
        Car car = new Car();
        car.setTire(tire);   // setter 의존성 주입
    }
}

생성자를 통해 의존성을 주입하면 한번 장착한 타이어는 더 이상 타이어를 교체할 수 없다는 문제점이 존재한다. 운전자가 원할 때 타이어를 교체하고 싶다면 setter 의존성 주입을 사용해야 한다.

 

3) 필드 주입

 생성자 의존성 주입을 할 때도 생성자에 실수로 필드를 적지 않을 수 있다. 이러면 컴파일 에러가 발생하지 않기 때문에.. 테스트 코드를 실행해보기 전까지는 알 수 없다.

 

그래서 이러한 경우를 사전에 방지하고자 필드에 final 키워드를 사용하는 것을 권장한다. final 키워드가 붙어있는데 생성자에 초기화 되지 않는다면 컴파일 에러가 발생하기 때문에 개발자의 실수를 사전에 막을 수 있다는 장점이 있다.


 

 

4. AOP(Aspect Object Programming, 관점 지향 프로그래밍)

AOP : 관점별로 나눠 모듈화해서 필요할때마다 끼워쓴다.

어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어 보고 그 관점을 기준으로 각각 모듈화하는 방법이다. 즉, 코드를 부분적으로 나눠서 중복되는 코드들을 Aspect(관점별로)를 이용해서 모듈화한(=묶는)다.

로깅, 트랜잭션, 보안 등 여러 모듈에서 공통적으로 사용하는 기능을 분리하여 관리 할 수 있다.

각각의 클래스가 있다고 가정하자. 각 클래스들은 서로 코드와 기능들이 중복되는 부분이 많다. 코드가 중복될 경우 실용성과 가독성 및 개발 속도에 좋지 않다. 중복된 코드를 최대한 배제하는 방법은 중복되는 기능들을 전부 빼놓은 뒤 그 기능이 필요할때만 호출하여 쓰면 훨씬 효율성이 좋다.

즉, AOP는 여러 객체에 공통으로 적용할 수 있는 기능을 구분함으로써 재사용성을 높여주는 프로그래밍 기법이다.

 

5. PSA (Portable Service Abstraction, 일관된 서비스 추상화)

환경의 변화와 관계없이 일관된 방식의 기술로의 접근 환경을 제공하려는 추상화 구조를 의미한다. POJO 원칙에 따라 가벼워지고 생산성이 높아진 Spring은 PSA 방식으로 추상화가 되어있어 가능하다.

Java Framework에서 사용 가능한 라이브러리들은 다양하지만 각자의 사용 방법이 다르다. 만약 MySQL 사용하던 시스템에서 DB를 Maria DB로 변경한다면 기존 소스를 일일히 수정해줘야 하지 않겠는가? 이럴 때 Spring을 사용하면 동일 사용방법을 유지한 채로 DB를 변경할 수 있다. Spring이 데이터베이스 서비스를 추상화한 인터페이스를 제공해주기 때문이다.(이 경우 Java를 이용해서 DB에 접근하는 방법을 규정한 인터페이스를 JDBC라고 한다.)

쉽게 말해 중간 어댑터(Adapter)가 하나 있는 것이다. 같은 일을 하는 다수의 기술을 공통의 인터페이스로 제어할 수 있게 한다.

 

🍀 Spring  MVC 구조

  • 모델-뷰-컨트롤러 패턴 : 소프트웨어 디자인 패턴 중 하나
  • M (Model) / V (View) / C (Controller)
    • Model : 어플리케이션의 정보나 데이터, DB 등을 말합니다.
    • View : 사용자에게 보여지는 화면, UI를 말합니다. 모델로부터 정보를 얻고 표시합니다.
    • Controller : 데이터와 비즈니스 로직 사이의 상호 동작을 관리합니다. 즉, 모델과 뷰를 통제합니다. MVC 패턴에서 View와 Model이 직접적인 상호 소통을 하지 않도록 관리합니다.

MVC 패턴은 크게 MVC 1 패턴과, 스프링이 채택한 MVC 2 패턴으로 나눌 수 있습니다.

MVC1

MVC1 패턴의 경우 View와 Controller를 모두 JSP가 담당하는 형태를 가집니다. 즉 JSP 하나로 유저의 요청을 받고 응답을 처리하므로 구현 난이도는 쉽습니다.

단순한 프로젝트에는 괜찮겠지만 내용이 복잡하고 거대해질수록 이 패턴은 힘을 잃습니다. JSP 하나에서 MVC 가 모두 이루어지다보니 재사용성도 매우 떨어지고, 읽기도 힘들어집니다. 즉 유지보수에 있어서 문제가 발생합니다.


MVC2

MVC2 패턴은 널리 표준으로 사용되는 패턴입니다. 요청을 하나의 컨트롤러(Servlet)가 먼저 받습니다. 즉 MVC1과는 다르게 Controller, View가 분리되어 있습니다. 따라서 역할이 분리되어 MVC1패턴에서의 단점을 보완할 수 있습니다. 그러므로 개발자는 M, V, C 중에서 수정해야 할 부분이 있다면, 그것만 꺼내어 수정하면 됩니다. 따라서 유지보수에 있어서도 큰 이점을 가집니다.

MV2는 MVC1 패턴보다 구조가 복잡해질 수 있지만, 개발자가 이러한 세부적인 구성까지 신경쓰지 않을 수 있도록 각종 프레임워크들이 지금까지 잘 발전되어 왔습니다. 그 중에서 대표적인 것이 바로 스프링 프레임워크입니다.

 

스프링 프레임워크 MVC2 패턴

스프링에서는 유저의 요청을 받는 DispathcerServlet이 핵심입니다. 이것이 Front Controller의 역할을 맡습니다.

Front Controller(프런트 컨트롤러)란, 우선적으로 유저(클라이언트)의 모든 요청을 받고, 그 요청을 분석하여 세부 컨트롤러들에게 필요한 작업을 나눠주게 됩니다.

 

즉, Front Controller

1. 클라이언트 요청에 맞는 Controller 클래스에 매핑해주는 HandlerMapping에게 검색을 요청하고 => "야 찾았어!"

2. 위에서 매핑된 Controller가 비지니스 로직을 수행하고 => "일하는중"

3. 로직을 수행한 결과물들을 가지고 있는 ViewResolver에게 "이런 이름을 가진 view를 줘" 라고 요청하고 => "결과물 여기"

4. ViewResolver에게 받은 알맞은 결과물을 클라이언트에게 결과화면으로 리턴합니다. => "니가 원하던거 줄께"

 

와 같은 역할을 하게 됩니다.


스프링 부트 프레임워크 (Spring Boot Framework)

🍀 스프링 부트(Spring Boot) 란?

스프링이 기존 기술에서 복잡성을 줄인 프레임워크지만, 그럼에도 불구하고 사용 시 여러 사항들을 설정해줘야 한다.
Spring Boot는 이러한 설정 내용을 간략히 줄여준 프레임워크다. 그렇게 될 수 있는 이유는 Spring Boot가 기존의 복잡한 설정을 대신 해주기 때문이다.
 
Spring Boot는 자체적인 웹 서버를 내장하고 있어, 기존 스프링보다 빠르고 간편하게 배포할 수 있다. 또한 독립적으로 실행 가능한 Jar 파일로 프로젝트를 빌드할 수 있어, 클라우드 서비스 및 도커와 같은 가상화 환경에도 빠르게 배포 가능하다.

 

반응형
LIST
반응형
SMALL

컨트롤러에서 요청/응답 처리하는 법

protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {

하나하나 뜯어보자면,

protected : java 접근자, 같은 폴더(패키지)및 그 클래스를 상속(extends)해서 구현하는 경우 접근이 가능 
void : return 되는 타입이 없음을 의미 
HttpServletRequest,HttpServletResponse : 웹브라우저 URL로 servlet이 요청할 시 요청,응답을 받기 위해 만드는 객체. 매개변수로 가지고 있는거임. WAS가 웹브라우저로부터 Servlet 요청을 받으면 req객체 생성해서 저장하고 resp 객체를 생성해 응답을 담아 servlet에게 반환한다. 
throws ServletException,IOException : java.io.IOException 과 javax.servlet.ServletException 예외를 던져야 합니다. 그냥 서블릿 규칙임.

 

HttpServletRequest 과 HttpServletResponse 메소드 정리

HttpServletRequest 과 HttpServletResponse 메소드 정리 HttpServletRequest 를 간단하게 req라고 해봅시다. req를 사용하면, 값을 받아올 수가 있는데, 회원정보를 보냈다면 req 객체 안에 모든 데이터들이 들어가

heannim-world.tistory.com

 

반응형
LIST
반응형
SMALL

HttpServletRequest 과 HttpServletResponse  메소드 정리

HttpServletRequest 를 간단하게 req라고 해봅시다. req를 사용하면, 값을 받아올 수가 있는데, 회원정보를 보냈다면 req 객체 안에 모든 데이터들이 들어가 있다. 따라서 req 객체의 몇가지 메소드들을 사용해서 원하는대로 꺼내쓰면 됨.

HttpServletRequest 메소드 메소드 설명
req.getMethod() get방식과 post방식을 구분할 수 있다.
req.getSession() 세션 객체를 얻는다.
req.getProtocol() 해당 프로토콜을 얻는다.
req.getParameter() 원하는 데이터를 꺼낼때(반환타입 String)
req.getContextPath()  프로젝트 Path만 가져옵니다.
req.getRequestURI()  프로젝트 + 파일경로까지 가져옵니다.
req.getRequestURL() 전체 경로를 가져옵니다.
req.getQueryString()
쿼리스트링을 얻는다.
req.ServletPath()  파일명만 가져옵니다.
req.getRealPath()  서버 or 로컬 웹 애플리케이션 절대결로 가져옵니다. 
req.setCharacterEncoding("UTF-8") POST방식으로 보내는 값이 '한글'일 경우 깨지지 않게 전달하기 위해 사용(GET은 톰캣에서 기본 UTF-8 적용되어있음)
req.setContentType("text/html;charset=utf-8") 서블릿에서 직접 브라우저에 출력해줄경우 브라우저에게 어떤 인코딩 방식을 쓸 것인지 전달
req.getwriter() java.io의 PrintWriter 클래스를 리턴 타입으로 한다. PrintWriter 클래스는 바이트를 문자 형태 객체바꿔주는데 클라이언트에게 문자형태로 응답하고 싶기 때문. getWriter()는 '쓰기'로 응답하겠다는 말로, 응답으로 내보낼 출력 스트림을 얻어낸 후 out.print(HTML태그) 를 써서 스트림에 텍스트를 기록한다.

HttpServletResponse를 간단하게 resp라고 해봅시다. HttpResponseServlet을 사용하여 Http Response 메시지를 생성/응답한다.

HttpServletResponse 메소드 메소드 설명
resp.setContentLength() 컨텐츠 길이 설정
resp.setHeader()  응답하는 데이터의 타입
resp.setStatus("응답코드") 응답코드를 지정할 수 있다. http 응답코드 200으로 적어도 되지만 이미 선언되어있는 상수를 사용하는게 의미 있는 값으로 사용할 수 있음.
resp.setCharacterEncoding("UTF-8") 응답할 때 문자의 인코딩 형태를 구한다.
resp.setContentType("application/json") 서블릿에서 직접 브라우저에 출력해줄경우 브라우저에게 어떤 인코딩 방식을 쓸 것인지 전달.
application/json은 utf-8이 스펙상 지정되어 있어 Response Header Content-Type에 charset을 추가해줄 필요가 없다.
addCookie(cookie) 쿠키를 지정한다.
sendRedirect(URL) 지정한 URL로 이동한다.
resp.getwriter() java.io의 PrintWriter 클래스를 리턴 타입으로 한다. PrintWriter 클래스는 바이트를 문자 형태 객체바꿔주는데 클라이언트에게 문자형태로 응답하고 싶기 때문. 응답으로 내보낼 출력 스트림을 얻어낸 후 out.xx(HTML태그) 를 써서 스트림에 텍스트를 기록한다.
resp.getOutputStream()
출력스트림에 접근하여 읽고 쓰는 등의 작업을 한다.

ActionForward란?

Action이 모든 작업을 끝내고서 이동하는 위치을 가상적으로 지정한 것이 ActionForward이다.
브라우저요청 -> ActionServlet -> [ActionForm] -> Action -> ActionForward의 path에 의해 지정된 다른 웹 요소

참고 : https://cobook.tistory.com/8

반응형
LIST
반응형
SMALL

+ Recent posts

반응형
LIST