스프링을 배우기 위해 꼭 알아야할 자바 기본 문법
어노테이션
스프링은 IoC(Inversion of Control) 컨테이너 관리권을 가지고 있어 어노테이션을 사용하여 의존성 주입을 한다.
어노테이션(Annotation) 종류
@Component
@RestController
@Controller
@Configuration
@Service
@Bean
의존성 주입(DI : Dependency Injection)
생성자(Constructor)가 IoC 컨테이너에 접근하는 것, 생성자에 타입이 있을 경우 Ioc 컨테이너에서 타입을 찾아낸다.IoC(Inversion of Control)
제어의 역전, 객체의 제어권이 스프링에게 넘어가는 것을 의미한다.어노테이션(Annotation)
컴파일시 JVM이 보는 주석으로 기본적으로 메타 데이터 역할을 한다.메타 테이터(Meta-Data)
데이터를 위한 데이터를 의미하며, 풀어 이야기하면 한 데이터에 대한 설명을 의미하는 데이터. (자신의 정보를 담고 있는 데이터)JVM(Java Virtual Machine)
명령을 직접 하드웨어에 내리는 것이 어려워 OS가 대신하는데, JVM은 OS에 맞게 자바 명령을 내리는 역할을 한다.(‘~.java’ 파일을 ‘~.class’ 파일로 OS에 맞게 실행시킨다.)
컴포넌트 스캔
스프링은 IoC 컨테이너 관리권을 가지고 있어 최초 실행시(ctrl+F11) ‘com.cos.프로젝트명’ 이하 파일만을 스캔하는데 이때 대신 heap 메모리에 데이터를 넣어준다. 즉, FrontController f = new FrowntController();
코드를 직접 입력하지 않아도 스프링이 IoC 컨테이너를 찾아가 new한다.
생성자(Constructor)
기본 생성자(Default Constructor)는 컴파일시 javac가 자동으로 생성하나 개발자가 따로 타입과 개수를 반영한 새로운 생성자를 만들 경우 기본 생성자는 사라진다. 그러므로 타입과 개수를 반영한 생성자를 만들 때 기본 생성자를 만들어두고 시작하면 편하다.생성자 상속
생성자의 상속은 타입이 일치하는 생성자와 내부 변수와 함수를 공유한다.
상속을 하는 이유는 다형성을 추구하기 위함으로 데이터를 추상화적으로 바라보는 것으로 느슨한 결합을 함으로서 프로그램을 설계와 유지보수(CI)를 용이하게 한다.
메모리 종류
8GB 메모리의 컴퓨터라면 80억개의 문자를 저장할 수 있다. 이 중에 반이 OS가 차지하는데 나머지 4GB를 자바에서 사용한다. 자바에서 사용하는 메모리에는 다음 세 종류가 있다.
Static 메모리
main 함수가 시작되기 전에 메모리에 떠서 main 함수가 종료될 때 메모리에서 사라진다. 주로 하나 밖에 없는 것, 무조건 떠 있는 것, 끝까지 띄우려는 것에 사용한다. 무조건 전역 변수이다. main이 실행되기 전에 뜨기 때문에 뜨는 타이밍 컨트롤할 수 없다는 단점이 있다. 예)태양, 공기, 달, 맵…
Stack 메모리
함수 내부에 존재하는 메모리로 생명주기가 짧으며 이를 지역변수라고도 한다. 실행시에 뜬다.
Heap 메모리
method를 new할 때 사용하는 메모리
오버로딩과 오버라이딩
오버로딩(Overloading)
동일한 이름의 method를 타입과 유형만 달리하여 몇 번이고 사용하는 기술
//오버로딩 예제 package ex01; class 정우성{ int hp=100; int power=30; } class 장동건{ int hp=100; int power=20; } class 원빈{ int hp=100; int power=20; } public class AttackApp { public static void attack(원빈 s1, 장동건 s2) { s2.hp = s2.hp - s1.power; } public static void attack(원빈 s1, 정우성 s2) { s2.hp = s2.hp - s1.power; } public static void attack(정우성 s1, 장동건 s2) { s2.hp = s2.hp - s1.power; } public static void main(String[] args) { // TODO Auto-generated method stub } }
오버라이딩(Overriding) : 무효화
부모 클래스와 자식 클래스의 이름이 같을 경우 부모 클래스를 무효화시키는 기술(재정의)
//오버라이딩 예제 package ex01; class Animal{ public void sound() {} } class Cat extends Animal{ public void sound() { System.out.println("야옹"); } } class Dog extends Animal{ public void sound() { System.out.println("멍멍"); } } public class Test2App { public static void play(Animal d) { d.sound(); } public static void main(String[] args) { Dog d = new Dog(); play(d); Cat c = new Cat(); play(c); } }
Getter & Setter
행위를 통해 상태에 접근하는데 이때 실수 방지를 위해 상태를 private 변수로 잡는다. 일반적인 방법으로 접근할 수 없는 private에 담긴 변수를 확인하기 위한 public 변수를 만들어주는데 이것이 바로 Getter와 Setter이다.
//Getter & Setter 사용 예제 package ex01; class 엘리스 { private int 목마름 = 100; //상태 : 행위(method)로 변경한다 //private에 접근할 수 없음으로 get으로 목마름 변수를 읽어주는 메소드를 만든다 public int get목마름() { return 목마름; } public void 물마시기() { //행위 this.목마름 = this.목마름 - 50; } } public class Test3App { public static void main(String[] args) { 엘리스 e = new 엘리스(); e.물마시기(); System.out.println(e.get목마름()); } }
Interface
자바 프로그램에서는 감시자 역할의 리스너를 만들어 사용자에 의해 이벤트가 발생하면 이를 이벤트 루프에 등록하는데 이때 OS가 해당 메서드명을 알아야한다.
자바는 일급객체가 클래스이기 때문에 메서드는 혼자서 메모리에 띄워지지 않으므로 반드시 클래스와 인터페이스 내에 선언해야 한다. 개발자가 사전에 행위(이벤트에 대한 결과)를 정의할 수 있는 경우에는 클래스를 사용하고 행위를 정의할 수 없는 경우에는 인터페이스를 사용한다.
이때 메서드명을 일치시키기 위한 강제적인 약속(프로트콜)을 하게 된다. 이를 갑과 을의 약속이라고 한다. 인터페이스로 강제성을 부여함으로서 개발자의 실수를 방지할 수 있고 공통 행위에 대한 기능을 제공해 줄 수 있다.
인터페이스 특징
- 추상 메서드를 가진다
- 변수를 만들면 자동으로 앞에 public static final이 생략된다.
- 인터페이스를 메모리에 로드하려면 익명 클래스를 만든다.
- 추상메서드는 무조건 자식이 구현해야 한다.
인터페이스의 역할
함수를 넘길 때 사용(자바에서 메서드는 1급 객체가 아니다.)
- 클래스 넘기기 (행위가 정해져 있을 때)
- 인터페이스 넘기기 (행위가 정해져 있지 않을 때)
cf ) 프로토콜 : 동등한 약속
package com.cos.blogapp.test; // 에이 컴퍼니 // 사장 : 야!! 우리 프로그램에 동물들이 특이한 기능!! - 서빙 interface Owner{ void serving(); } abstract class Animal { abstract void sound(); abstract void walk(); } class Dog extends Animal implements Owner{ void sound() { System.out.println("멍멍"); } void walk() { System.out.println("달린다"); } @Override public void serving() { System.out.println("강아지 서빙"); } } class Cat extends Animal implements Owner{ void sound() { System.out.println("야옹"); } void walk() { System.out.println("달린다"); } @Override public void serving() { System.out.println("야옹이 서빙"); } } class Bird extends Animal implements Owner{ @Override void sound() { System.out.println("짹짹"); } void walk() { System.out.println("걷다"); } @Override public void serving() { System.out.println("새 서빙"); } } public class TestApp { public static void start(Animal a) { a.sound(); a.walk(); } public static void main(String[] args) { start(new Bird()); } }