Spring boot 빠르게 시작해보자

Spring boot를 이용하여 API 서버를 개발해보자!

start.spring.io 에서 설정해서 시작해도 된다.

maven을 이용하여 시작해보자.
일단 메이븐 프로젝트를 생성한다.
그럼 pom.xml 파일이 있을 것이다.
pom파일에 아래와 같이 추가한다.

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
        <relativePath/>
    </parent>

위의 아이는 버전관리 및 플러그인, 인코딩 자바 버전 등이 설정 되어있다.
참으로 좋은 녀석이다.
다음으론 아래와 같이 dependencies 들을 추가한다.


<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>

첫 번째 있는 spring-boot-starter 에는 스프링 부트의 핵심인?(필자기준 아닐수도 있음) autoconfigure가 포함되어 있다.
그리고 스프링 부트는 기본으로 logback을 사용하고 있다.
그런데 가만보면 이상한점이 있다. 버전을 정보가 없다. 그 이유는 parent에서 관리는 해주기 때문이다.
니가 뭔데 버전을 관리하냐 나는 내가 할거다 하는 사람은 버전을 명시적으로 써주면 된다.

흠. 설정이 끝났다.
메인 클래스 만들자.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

메인 클래스 작성도 끝났다. 실행시켜보자. 아무 에러가 없다면 준비는 끝났다.
이 클래스에 중요한건 @SpringBootApplication 어노테이션이다.
저 안에는 @Configuration ,@EnableAutoConfiguration,@ComponentScan 애노테이션이 있다.
아주 쓸모있는 아이다.

이제 API를 서버를 만들자.
서버를 띄우기 위해선 아래와 같이 추가를 한다.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

이놈도 무시무시한놈이다. 내장톰캣을 사용하고 웹에 필요한 라이브러리들을 추가해준다.
다음으론 메인 클래스를 조금 수정하자. 아니 추가하자.

@SpringBootApplication
@RestController
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @RequestMapping("hello")
    public String hello(){
        return "hello world";
    }
}

이제 모든 준비는 끝났다.
메인 클래스를 실행시키자!
서버가 시작되었면 http://localhost:8080/hello로 접속을 해보자
hello world가 웹페이지에 있다면 성공적으로 API서버를 만들었다.

참고 : Starter POMs

순열이란

순열

  • 서로 다른 n개에서 r개를 택하여 일렬로 배열하는 것을 n개에서 r개를 택하는 순열
  • nPr로 나타낸다.

문제) 1,2,3,4,5의 다섯개 숫자중에서 서로 다른 세 개의 숫자를 사용하여 만들 수 있는 세 자리의 자연수의 개수를 구하여라

  • 5P3 = 5×4×3 = 60

특수한 경우

문제) m,a,t,h의 네 개 문자중 m,t 이웃하도록 배열

  • (mt), a, h를 한덩어리로 본다. 그럼 3!
  • 또한 mt, tm 도 가능하기 때문에 2!
  • 3!× 2!

문제) 1~5 5장 숫자카드중 세자리 짝수의 경우의수는?

  • 조건을 보면 짝수 조건이다.
  • 그럼 마지막의 올 수 있는 카드는 2 또는 4 밖에 올 수 없다. XX2 또는 XX4
  • 그럼 첫번째 자리에 올 수있는 카드의 개수는 4 두번째는 3 그리고 마지막 자리엔 2개
  • 4 × 3 × 2

중복 순열

  • 순열과 마찬가지로 n개중에 r개를 택하는데 중복을 허용하는 순열이다.
  • n∏r로 나타낸다.

문제) 1~5 숫자카드중 세자리 자연수를 만들수있는 개수는? (중복허락)

  • 첫 번째자리에 올 수있는 카드의 개수는 5개 두 번째도 5개 세 번쨰도 5개
  • 5∏3 으로 나태낸다.
  • 5 × 5 × 5 개수이다.

문제) 1 2 두개의 카드중 중복을 허용해서 세자리 자연수로 나타낼수 있는 개수는

  • 첫 번째자리에 2개 두 번째도 2개 세번쨰도 2개
  • 2∏3
  • 2 × 2 × 2

n∏r중에 n은 중복되는 것이 온다.
쉽게 설명에서 n는 집 r은 사람이라 생각하면 된다.

문제) 5명의 유권자중에 2명의 후보에게 투표 방법은?

  • A라는 후보에 5명이 모두 투표 할 수 있다. 이건 A A A A A 라 볼 수 있다.
  • 또는 A에 두명 B엔 3명이 투표를 할 수 있다. 이건 A A B B B 라 볼 수 있다.
  • 그럼 2∏5가 정답이다.

같은 것이 있는 순열

  • n개 중에서 서로 같은 것이 각각 p개,q개 … r개씩 있을 때 이들 n개를 모두 일렬로 배열하는 순열

문제) s, o, c, c, e, r 6개 문자를 일렬로 배열하는 경우의 수

  • 일단 6개 숫자중 같은 것이 없다고 생각하고 배열 6!
  • 그리고 같은 것이 c 두개가 있으므로 2!
  • 두개를 나눠주면 된다.
  • 6!/2!

문제) a,b,c,d,e,f 6개의 문자중 일렬로 배열하는 경우의 수 하지만 b가 d 보다 항상 앞에 있어야 된다.

  • 예로 abcdef 와 adcbef가 배열로 있을 때 두번째는 d가 b보다 앞에 있기 때문에 1개로 취급한다.
  • 1개로 취급 즉 같은 것으로 취급하면 된다.
  • 6!/2!이다.

문제) 숫자 1이 적힌 카드가 3장, 숫자 2가 적힌 카드 2장, 숫자 0이 적힌 카드 1장이 있다. 이 6장의 카드를 일렬로 배열하여 6자리의 자연수를 만들 때, 서로 다른 자연수의 개수는?

  • 일단 0은 맨 앞자리로 못온다.
  • 맨 앞자리에 올수 있는 카드는 1 또는 2
  • 1이 맨 앞에 올 때 올 수 있는 카드는 1 1 2 2 0 5!/2!2! = 30
  • 2가 맨 앞에 올 때 올 수 있는 카드는 1 1 1 2 0 5!/3! = 20
  • 두개를 더하면 된다. 50

java Proxy 기능으로 AOP

proxy 기능으로 AOP를 만들어 보자!

java.lang.reflect 패키지에 InvocationHandler 인터페이스가 존재한다. 이 인터페이스를 이용해 AOP를 구현할 수 있다.
간단히 어떤수의 두배하는 메소드를 만들어보자

class TwiceImpl implements Twice {

    @Override
    public int twice(int x) {
        return x * 2;
    }
}

interface Twice {
    int twice(int x);
}

이 코드를 사용하려면 이렇게 하면 된다. 위의 클래스의 인터페이스를 만든이유는 인터페이스가 있어야 java의 Proxy AOP를 만들수있다.

Twice twice = new TwiceImpl();
System.out.println(twice.twice(5));

이제 InvocationHandler 인터페이스를 이용하여 AOP를 구현해보자

class JavaProxyHandler implements InvocationHandler {
    private Object target;

    public JavaProxyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("메소드 호출 전");
        int result = (int) method.invoke(target, args);
        System.out.println("메소드 호출 후");
        return result;
    }
}

이제 Proxy가 구현되었다.

그럼 Proxy 객체로 다시 호출해보자!

Twice twice = new TwiceImpl();
Class<? extends Twice> twiceGetClass = twice.getClass();
Twice twiceProxy = (Twice) Proxy.newProxyInstance(
        twiceGetClass.getClassLoader(),
        twiceGetClass.getInterfaces(),
        new JavaProxyHandler(twice));
System.out.println(twiceProxy.twice(5));

그럼 결과는 다음과 같을 것이다.

메소드 호출 전
메소드 호출 후
10

참고 : AspectJ로 구현한 AOP