이론을 싫어!

[Spring] 원격 프로그램 실행해보기 !(실행방법 본문

Spring and Springboot

[Spring] 원격 프로그램 실행해보기 !(실행방법

이론을 싫어! 2023. 3. 5. 22:19
반응형

우리가 원격이라는 말은 온라인 상(인터넷 상)에서 다수의 공급자가 서비스나 용역에 제공하는 것을 말한다.

 

즉, 결국 쉽게 말하면 내 컴퓨터가 다른 컴퓨터에 접근 할수 있도록 하는 것이다. 

 

Spring에서 원격프로그램을 실행을 할려고 하면 2가지의 규칙이 존재한다.

 

1. 프로그램 등록 

 

2. URL과 프로그램 연결

 

이다. 

 

먼저 1. 프로그램 등록은 @Controller 의 어노테이션을 쓴다. 

 

그러면 Controller은 무엇인가??

 

Controller은 보통 사용자의 요청을 처리하고 난뒤에 데이터나 객체를 뷰와 함께 넘겨주는 역할을한다.

 

예를 들어 햄버거 가게에 고객이 주문을 하게 되면 그 주문을 받고 다 만든 햄버거를 주는 역할이 Controller의 역할이다.

 

Controller은 햄버거를 만들어 주지 않고 그냥 주문이 들어오는 것을 받고 다 만든 햄버거를 주는 역할을 한다.

 

2. URL과 프로그램 연결은 @RequestMapping의 어노테이션을 쓴다.

 

그러면 RequestMapping은 무엇일까? 

 

Requset -> 요청이다 .

 

즉, 사용자가 요청이 들어왔을때 어떤 컨트롤러 (메소드)가 호출되어야되는지 알려주는 표지판이라고 생각하면 된다.

 

 

(예시)

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller //1. 원격 호출 가능한 프로그램으로 등록 
public class Hello {
    
    
    @RequestMapping("/hello"// 2. URL 과 메소드를 연결 
    public void main() {
        System.out.println("hello!");
    }
cs

 

// 2. URL 메소드를 연결 이라고 적혀있는데 URL은 또 무엇인가...

 

URL 을 인터넷에 검색을 하게 되면  " 인터넷에서 웹 페이지, 이미지, 비디오 등 리소스의 위치를 가리키는 문자열 " 이라고 적혀있다. 

 

단순하게 설명을 하면 "링크" 라고 생각하면 된다. 

 

우리가 네이버에 들어가기 위해서 링크로 들어가게 되는데 네이버의 링크가 "http://www.naver.com" 이다 . 

 

이것이 URL 이다. 

 

----------------------------------------------------------------------------------------------------------------------

프로그램 실행 

 

 

톰캣을 실행시킨 다음에 

 

1
http://localhost:8080/ch2/hello
cs

우리가 만든 프로그램에 접속하기 위한 URL이다. 

 

조금 설명을 포트의 번호는 8080으로 설정을 해놨기 때문에 접근하기 위해서는 자기가 톰캣에 설정한 포트번호를 써야하고 

 

/ch2는 프로젝트 명이다 . 

 

프로젝트 명

프로젝트 명이 뭔지 잘 모르겠으며 위에 사진을 참고 하면 볼수 있다. (파일 명이 아닌 프로젝트 명임)

 

그리고 난뒤에 /hello는 내가 2번 @ReqiestMapping에서 설정한 주소를 붙여준것이다. 

 

즉, 단순하게 URL을 정리하면 ch2의 프로젝트 안에 hello의 URL 과 연동된 메소드를 요청합니다. 라는 뜻으로 해석할수 있다.

 

 

위의 주소를 검색하게 되면 

 

URL 호출 후 모습

위의 사진처럼 파일을 찾을수가 없다고 뜬다.

 

그러면 실패 한 것인가?? hello! 는 어디에 있나?? 

 

그것은 콘솔에 뜬다.

 

실행후 결과 출력

콘솔을 확인 해보면 hello! 라고 콘솔에 찍힌것을 볼수 있다. 

 

이 뜻은 프로그램 연결에 선공했다는 뜻이다. 

 

똑같은 주소를 찍으면 콘솔 밑에 계속 hello! 라고 찍히게 된다.

 

 

여기서 문제!!!

무조건 메소드는 public void 를 써야되나???

 

결론은 아니다 . 사용에 따라서 달라질수 있다. 

 

첫번째. static 메소드가 좋을까? 인스턴스 메소드가 좋을까? 

 

말로 설명하는 것보다 코드(예시2)를 보면 좀더 쉽게 이해가 될것이다 .

 

(예시2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http@Controller //1. 원격 호출 가능한 프로그램으로 등록 
public class Hello {
    int aa= 10;    // 인스턴스 변수
    static int bb=20;  // static 변수 
    
    @RequestMapping("/hello")  // 2,URL 과 메소드를 연결 
    private void main() {   // 인스턴스 메소드 (aa,bb ,둘다 사용가능하다.)
        System.out.println("Hello");
         System.out.println(aa);  // o
         System.out.println(bb);  // o
    }
    
    public static void main2() { // static 메소드(bb 만 사용가능하다.) static 메소드는 인스턴스 메소드를 쓸수 없다.
//     System.out.println(aa);  // x
     System.out.println(bb);  // o
    }
}
cs

 

위의 예시 코드를 보면 좀더 쉽게 구분이 가능하다.

 

만약에 aa 라는 인스턴스 변수와 bb 라는 static 변수가 있다고 가정을 하자. 

 

인스턴스 메소드 (main메소드) 는 인스턴스 변수와 static 변수 둘다 사용이 가능하다. 

 

하지만 static 메소드 (main2메소드)는 static 변수만 사용가능하고 인스턴스 변수는 사용 불가하다 .

 

물론 static 메소드 사용 가능하지만 꼭 필요한 부분이 아니라면 인스턴스 메소드를 쓰는것이 훨씬 사용하기 편리하다.

 

 

두번째 . 무조건 public 인가?? 

 

아니다. private 도 쓸수 있다.

 

 

private 도 가능

 

위의 사진을 보면 private으로 해도 실행이 되는것을 알수 있다.

 

우리가 private 은 절대로 외부에서 호출이 불가능하다고 배웠다. 

 

하지만 되는 이유는 무엇일까? 

 

@RequesetMapping 이 아까 URL과 메소드를 연결한다고 했다 .

 

이말은 외부에서 메소드를 접근 가능하게 만든다는 것이다. 

 

그러다보니 접근 제어자 상관없이 접근을 가능할수 있게 만든것이다 .

 

결국 이유는 Reflection API를 사용하기 때문이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
import java.lang.reflect.Method;
 
public class Main {
  
    public static void main(String[] arg)throws Exception{
    //        Hello hello =new Hello();
    //        hello.main();  // private이라서 외부 호출 불가하다.
            
            //Reflection API 를 사용 - 클래스 정보를 얻고 다룰 수 있는 강력한 기능 제공 
            //java.lang.reflect 패키지를 제공 
         // Hello 클래스의 Class 객체(클래스의 정보를 담고 있는 객체를 얻어온다).
      Class helloClass =Class.forName("com.sdg99018.ch2.Hello");
      Hello hello= (Hello)helloClass.newInstance(); //  Class 객체가 가진 정보로 객체 생성 
      Method main= helloClass.getDeclaredMethod("main");
      main.setAccessible(true);  // private인 main()을 호출가능하게 한다.
      
      main.invoke(hello); // hello.main()
      
    }
}
cs

 

이처럼 Reflection API 가 Spring Framework에서 굉장히 많이 쓰이고 있다는 것을 알수 있다.

 

다음에는 좀더 쉽고 재미있게 알려드리도록 하겠습니다. 감사합니다^^