
엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크이다.
웹 애플리케이션을 쉽고 빠르게 만들 수 있도록 도와주는 자바의 웹 프레임워크이다.
스프링 프레임워크에 톰캣(Tomcat)이라는 서버를 내장하고 여러 편의 기능을 추가한 것이다.

다른 객체를 직접 생성하거나 제어하는 것이 아니라, 외부에서 관리하는 객체를 가져와서 사용하는 것이다. 이는 객체의 생명주기 및 의존성 관리를 담당하는 IoC 컨테이너를 제공한다.
public class A {
private B b; // 코드에서 객체를 생성하지 않음. 어디선간 받아온 객체를 b에 할당
}
제어 역전을 구현하기 위해 사용하는 방법이며, 어떤 클래스가 다른 클래스에 의존한다는 뜻이다.
스프링은 의존성 주입을 통해 객체 간 관계를 설정하며, 애플리케이션의 결합도를 낮추고 유연성과 테스트 용이성을 향상시킨다.
이때 사용되는 개념이 빈 (Bean)인데, @Autowired라는 anntation으로 스프링 컨테이너에 있는 빈을 주입하는 역할을 한다.
public class A {
@Autowired // A에서 B를 주입받음
B b;
}

프로그래밍에 대한 관심을 핵심 관점, 부가 관점으로 나누어서 관심 기준으로 모듈화하는 것이다.
스프링에서 제공하는 다양한 기술들을 추상화해 개발자가 쉽게 사용하는 인터페이스를 의미한다.
간단히 말하면, 어느 기술을 사용하던 일관된 방식으로 처리하도록 하는 것이다.

이렇게 스프링부트의 기본적인 특징을 알아봤으니, Annotation에 대하여 알아보자.
자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여 사용한다.
즉, @를 이용하여 소스코드가 컴파일되거나 실행될 때 컴파일러 및 다른 프로그램에게 필요한 정보를 전달해주는 문법 요소이다.
1) Bean 등록
1-1) 등록 방식
@Component : 일반적인 스프링 빈@Repository : 비즈니스 로직 담당 클래스@Service : DB 접근 클래스@Controller : 웹 요청 처리 클래스@Bean : 메서드 선언부에 작성@Configuration : 스프링 설정 클래스 표시용. 최상단에 작성한다.1-2) @Scope : Bean의 life cycle 설정
종류
2) DI 관련
@Autowired : 속성, 생성자, setter 메서드, 일반 메서드 위에 선언. Spring에서 지원 (객체끼리 순환참조 발생 가능성을 줄이기 위해 Autowried로 주입받는 것을 더 선호한다.)
@Resource(name="bean 이름") : 속성, setter 메서드 위에 선언.
@Inject : 속성, 생성자, setter 메서드, 일반 메서드 위에 선언. JAVA에서 지원
@Qualifier("bean 이름") : @Autowired로 주입할 때, 동일한 타입의 객체가 여러 개일 때 name으로 구별한다.
3) AOP 관련
@Aspect, @Pointcut, 어드바이서(@Before, @After, @AfterReturning, @AfterThrowing, @Around), @Transactional
4) Web
@RequestMapping : url mapping (모든 요청 방식을 처리해준다)
@RequestParam : String, Primitive, Map에 대한 요청 데이터 지정
@ModelAttribute : DTO에 대한 요청 데이터 지정
@ExceptionHandler : 에러 처리하는 함수 선언
@ControllerAdvice : 에러 처리하는 class 선언
@PathVariable : 비동기 통신으로 전달된 get, delete 방식의 요청 데이터를 url에서 추출해 올 때 지정
@RequestBody : 비동기 통신으로 전달된 put, post 방식의 요청 데이터 추출
@ResponseBody : 응답을 특정 url로 이동하지 않고 직접 출력
@RestController : Restful API를 위한 Controller 선언
5) Spring Boot
@SpringBootApplication : spring boot를 실행
@Component(basePackages='') : base package 설정
@MapperScan(basePackages = { "com.ssafy.**.model.dao" }) : mybatis Mapper에 대한 basePackages 설정
6. Controller 계열
@RestController
@RequestMapping
@CrossOrigin
REST (Representational State Transfer) 아키텍처 스타일을 따르는 API이다.
웹의 기본 원칙 (HTTP 프로토콜, URI, 메서드 등)을 활용하여 시스템 간 데이터를 주고받는 방식을 정의한 설계 방식이며, 즉 인터넷 상에서 자원(Resource)을 주고받기 위한 간단하고 표준화된 방법이다.

Content-Type: application/json 등)이외의 핵심원칙, 장단점, 모범 설계 사례는 아래 블로그에서 추가적인 정보가 있으니 보면 좋을 것 같다.
Create, Read, Update, Delete의 앞글자를 딴 단어로, 대부분의 애플리케이션에서 기본적인 데이터 관리 작업을 정의한다.
(http://localhost:8080/ureca/test?id=1&name=ureca&email=ureca@uplus.com)
@GetMapping
public ResponseEntity<String> hello(@RequestParam(value="id") String id,
@RequestParam(value="name") String name,
@RequestParam(value="email") String email){
logger.debug("id:{}", id );
logger.debug("name:{}", name );
logger.debug("email:{}", email );
ResponseEntity<String> response = new ResponseEntity<>("Success", HttpStatus.OK);
return response;
}
@GetMapping
public ResponseEntity<String> hello(@RequestParam Map<String, String> map){
logger.debug("id:{}", map.get("id") );
logger.debug("name:{}", map.get("name") );
logger.debug("email:{}", map.get("email") );
ResponseEntity<String> response = new ResponseEntity<>("Success", HttpStatus.OK);
return response;
}
@GetMapping
public ResponseEntity<Member> hello(@ModelAttribute Member member){
logger.debug("member:{})", member);
logger.debug("id:{}", member.getId() );
logger.debug("name:{}", member.getName());
logger.debug("email:{}", member.getEmail() );
ResponseEntity<Member> response = new ResponseEntity<>(member, HttpStatus.OK);
return response;
}
@PostMapping
public ResponseEntity<String> regist(@RequestBody Book book) {
logger.debug("regist-books:{}", book);
service.insert(book);
return new ResponseEntity<String>(SUCCESS, HttpStatus.CREATED);
}
@PutMapping
public ResponseEntity<String> update(@RequestBody Book book) {
logger.debug("update-book:{}", book);
service.update(book);
return new ResponseEntity<String>(SUCCESS, HttpStatus.OK);
}
@DeleteMapping("/{isbn}")
public ResponseEntity<String> remove(@PathVariable("isbn") String isbn) {
logger.debug("remove-isbn:{}", isbn);
service.remove(isbn);
return new ResponseEntity<String>(SUCCESS, HttpStatus.OK);
}

@ControllerAdvice를 통해서 하나의 class에서 모든 에러를 관리할 수 있다.
package com.uplus.ureca;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
/**
* @ControllerAdvice
* 프로젝트에서 발생하는 모든 오류를 처리하는 기능
* */
/**
* error 메시지 처리 시 한글인 경우 깨지므로 한글 처리를 해야한다.
* Content-type : application/json;charset-UTF-8
* @ExceptionHandler
* 해당 컨트롤러에서 발생하는 오류를 처리하는 Annotaion
**/
@ControllerAdvice
public class ExceptionControllerAdvice {
private Logger logger = LoggerFactory.getLogger(getClass());
@ExceptionHandler
public ResponseEntity<String> handler(Exception e){
logger.error("TestController msg:{}", e.getMessage());
e.printStackTrace();
String msg = "처리 중 오류 발생";
if (e instanceof UrecaException) {
msg = e.getMessage();
}
//에러 메세지가 한글인 경우 깨지므로 한글 처리를 위한 응답 헤더 설정
HttpHeaders header = new HttpHeaders();
header.add("Content-type", "application/json;charset-UTF-8");
return new ResponseEntity<String>(msg, header, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
개발자들이 SQL 쿼리를 쉽게 작성하고, 관리할 수 있도록 도와주는 퍼시스턴스 프레임워크이다.
주로 JPA를 사용하지만, 해당 부트캠프에서는 백엔드 기초만 나가기 때문에 빠르게 할 수 있는 마이바티스로 진도를 나갔다.
SQL Map XML 파일을 통해서 작성하고, 강력한 매핑 기능을 제공하는 장점이 있어서 하나의 파일에서 SQL 작성이 가능하다.
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
<insert id="insert" parameterType="Book">
insert into book (isbn, title, author, price, describ, img)
values (#{isbn}, #{title}, #{author}, #{price}, #{describ}, #{img})
</insert>
<update id="update" parameterType="Member">
update members
<set>
<if test="name != null">name = #{name}, </if>
<if test="password != null">password = #{password}, </if>
<if test="email != null">email = #{email}, </if>
<if test="address != null">address = #{address}</if>
</set>
where id = #{id}
</update>
<delete id="remove" parameterType="string">
delete from book where isbn = #{isbn}
</delete>
이렇게 7일 간의 백엔드 기초 수업이 끝났다. 기간이 짧고 추석 연휴가 있다보니 흐름이 중간에 끊긴 것 같아 아쉬움이 많이 남는 것 같다.
백엔드는 제공받은 책으로라도 따로 공부를 해서 미니 프로젝트에 참여해야 할 것 같다.
이번 추석 연휴가 길어서 몸과 정신이 느슨해진 것 같아서 빠르게 정신 잡아야겠다.