Home

0

[Spring Core] - BeanDefinition

목차 [Spring Core] - 의존성 주입 방식 [Spring Core] - 컴포넌트 스캔과 의존성 주입 [Spring Core] - BeanDefinition [Spring Core] - 스프링 빈 [Spring Core] - 스프링 컨테이너 생성과 Bean 등록, 의존성 주입 [Spring Core] - 스프링 컨테이너 🔎 BeanDefinition - Bean 메타정보 관리 스프링 컨테이너는 BeanDefinition 을 이용해 스프링 빈을 생성합니다. 빈 메타 정보는 XML, 자바코드 등으로 작성되며 @Bean, <bean> 당 하나씩 메타정보가 생성됩니다. 스프링은 정의된 메타정보들을 읽어와 BeanDefinition 을 생성한 후 스프링 컨테이너에서 BeanDefinition 에 정의된 빈 메타정보를 이용해 스프링 빈을 생성합니다. ` 당 하나씩 메타정보가 생성됩니다. --> 🔎 BeanDefinitionReader - BeanDefinition 을 생성하기 위한 객체서로 다른 방식으로 정의된 빈 메타정보를 BeanDefinition 으로 생성하기 위해 스프링은 다양한 BeanDefinitionReader 를 제공합니다. AnnotationConfigApplicationContext 는 AnnotatedBeanDefinitionReader 를 사용해서 AppConfig.class 를 읽고 BeanDefinition 을 생성합니다. GenericXmlApplicationContext 는 XmlBeanDefinitionReader 를 사용해서 appConfig.xml 설정 정보를 읽고 BeanDefinition 을 생성합니다. 새로운 형식의 설정 정보가 추가되면, XxxBeanDefinitionReader를 만들어서 BeanDefinition 을 생성하면 된다.

0

[Spring Core] - 스프링 컨테이너 생성과 Bean 등록, 의존성 주입

목차 [Spring Core] - 의존성 주입 방식 [Spring Core] - 컴포넌트 스캔과 의존성 주입 [Spring Core] - BeanDefinition [Spring Core] - 스프링 빈 [Spring Core] - 스프링 컨테이너 생성과 Bean 등록, 의존성 주입 [Spring Core] - 스프링 컨테이너 스프링 컨테이너 생성 과정과 Bean 등록, 의존성 주입스프링 실행시 스프링 컨테이너가 생성되면 전달 받은 설정 정보를 이용해 스프링 빈을 생성 및 등록 합니다. 빈 등록이 완료된 후에는 설정 정보를 참고해 의존관계를 주입합니다. 이렇게 스프링은 빈을 생성하고 의존관계를 주입하는 관계가 나눠져 있습니다. 하지만 자바 코드로 빈을 등록하게 되면 객체의 생성자를 호출하면서 의존관계 주입까지 한번에 이뤄지게 됩니다. 1. 스프링 컨테이너 생성스프링 컨테이너를 생성할 때는 구성 정보를 지정해주어야 합니다. 구성 정보는 자바 클래스나 xml 을 이용해 정의할 수 있습니다. 스프링 컨테이너 생성시 설정 정보를 이용해 스프링 컨테이너를 생성합니다. 아래에서는 자바 클래스 AppConfig.class 를 설정 정보로 이용해 스프링 컨테이너를 생성합니다. //스프링 컨테이너 생성ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

0

[Spring Core] - 스프링 빈

목차 [Spring Core] - 의존성 주입 방식 [Spring Core] - 컴포넌트 스캔과 의존성 주입 [Spring Core] - BeanDefinition [Spring Core] - 스프링 빈 [Spring Core] - 스프링 컨테이너 생성과 Bean 등록, 의존성 주입 [Spring Core] - 스프링 컨테이너 스프링 빈 스프링 IoC 컨테이너에 의해 생성되고 관리되는 객체를 보고 스프링 빈이라 부릅니다. Bean 객체는 스프링 컨테이너에 의해 생성 및 관리되며 일반적으로 싱글톤 객체로 생성됩니다. Bean 끼리 의존관계가 있을 경우 의존성 주입을 통해 사용할 수 있습니다. 스프링 컨테이너에 객체를 Bean 으로 등록하는 방법 XML 에 직접 등록하는 방법 @ComponentScan 을 이용해 자동적으로 Bean 을 등록하는 방법 @Configuration 과 @Bean 을 이용하여 직접적으로 등록을 하면 된다. Bean 어노테이션으로 정의할 때는 @Configuration 가지고 있는 클래스 안에 정의해야 한다. @Configuration 안에서 @Bean 을 사용해야 싱글톤을 보장 받을 수 있습니다. XML 을 이용해 Bean 등록하기최근 스프링 부트의 등장으로 xml 을 이용해 스프링을 설정하는 방법은 잘 사용하지 않는 방식입니다. xml 을 이용해 스프링 컨테이너를 설정하는 것의 장점은 컴파일 없이 빈 설정 정보를 변경할 수 있다는 점이다.

0

[Spring Core] - 스프링 컨테이너

목차 [Spring Core] - 의존성 주입 방식 [Spring Core] - 컴포넌트 스캔과 의존성 주입 [Spring Core] - BeanDefinition [Spring Core] - 스프링 빈 [Spring Core] - 스프링 컨테이너 생성과 Bean 등록, 의존성 주입 [Spring Core] - 스프링 컨테이너 스프링 컨테이너와 IoC(Inversion of Control)객체의 생성, 객체간의 의존성 과 같은 프로그램의 흐름 을 개발자가 아니라 프레임워크나 외부 컨테이너에가 관리 해주는 것을 의미합니다. 즉, 프로그램에 대한 제어권이 개발자가 아니라 프레임워크나 외부 컨테이너에서 관리가 됩니다. 스프링의 핵심요소인 스프링 컨테이너는 객체의 생성과 관리, 의존성 주입, 생명주기등을 해주기 때문에 IoC 컨테이너 라고 불립니다. 스프링 컨테이너의 주요 기능스프링 컨테이너는 객체를 생성하고 컨테이너에 등록합니다. 이때, 스프링 컨테이너에 등록된 객체들을 스프링 Bean 이라 부르고 컨테이너는 등록된 Bean 의 생성, 초기화, 소멸까지의 전체적인 생명주기를 관리합니다. 스프링 Bean 들이 생성된 후 스프링 컨테이너는 객체간의 관계를 확인 후 설정에 따라 의존성을 주입합니다. Bean 으로 등록되지 않은 객체에 대해서는 의존성 주입이 이뤄지지 않습니다.

0

백준 - 14499 주사위 굴리기

https://www.acmicpc.net/problem/14499 체점 현황 문제 해설문제를 입력받는 곳에서 함정이 있다. 평소에 세로를 y, 가로를 x로 놓고 문제를 해결하는 사람들에게는 틀리기 너무 좋은 문제주사위의 현재 위치를 계속 추적하면서 주사위 상태도 계속해서 관리해야 한다. 위치를 쉽게 관리하기 위해서 전역변수를 통해 전역적으로 관리했다. #include <iostream>#include <vector>using namespace std;int n, m, x, y, k;int map[22][22];int cube[4][3];vector<int> command;void moveUp() { if (x - 1 >= 0) { x -= 1; int temp01, temp11, temp21, temp31; temp01 = cube[0][1]; temp11 = cube[1][1]; temp21 = cube[2][1]; temp31 = cube[3][1]; cube[0][1] = temp11; cube[1][1] = temp21; cube[2][1] = temp31; cube[3][1] = temp01; int next = map[x][y]; if (next == 0) { map[x][y] = cube[3][1]; } else { cube[3][1] = map[x][y]; map[x][y] = 0; } cout << cube[1][1] << '\n'; } else { return; }}void moveDown() { if (x + 1 < n) { x += 1; int temp01, temp11, temp21, temp31; temp01 = cube[0][1]; temp11 = cube[1][1]; temp21 = cube[2][1]; temp31 = cube[3][1]; cube[1][1] = temp01; cube[2][1] = temp11; cube[3][1] = temp21; cube[0][1] = temp31; int next = map[x][y]; if (next == 0) { map[x][y] = cube[3][1]; } else { cube[3][1] = map[x][y]; map[x][y] = 0; } cout << cube[1][1] << '\n'; } else { return; }}void moveRight() { if (y + 1 < m) { y += 1; int temp11, temp12, temp31, temp10; temp11 = cube[1][1]; temp12 = cube[1][2]; temp31 = cube[3][1]; temp10 = cube[1][0]; cube[1][1] = temp10; cube[1][2] = temp11; cube[3][1] = temp12; cube[1][0] = temp31; int next = map[x][y]; if (next == 0) { map[x][y] = cube[3][1]; } else { cube[3][1] = map[x][y]; map[x][y] = 0; } cout << cube[1][1] << '\n'; } else { return; }}void moveLeft() { if (y - 1 >= 0) { y -= 1; int temp11, temp12, temp31, temp10; temp11 = cube[1][1]; temp12 = cube[1][2]; temp31 = cube[3][1]; temp10 = cube[1][0]; cube[1][0] = temp11; cube[1][1] = temp12; cube[1][2] = temp31; cube[3][1] = temp10; int next = map[x][y]; if (next == 0) { map[x][y] = cube[3][1]; } else { cube[3][1] = map[x][y]; map[x][y] = 0; } cout << cube[1][1] << '\n'; } else { return; }}void moveCube() { int commandNum = command.size(); for (int i = 0; i < commandNum; i++) { int cntCommand = command[i]; if (cntCommand == 1) { moveRight(); } if (cntCommand == 2) { moveLeft(); } if (cntCommand == 3) { moveUp(); } if (cntCommand == 4) { moveDown(); } }}int main(void) { cin >> n >> m >> x >> y >> k; for (int i = 0; i < n; i++) { { for (int j = 0; j < m; j++) { cin >> map[i][j]; } } } map[x][y] = 0; for (int i = 0; i < k; i++) { int temp = 0; cin >> temp; command.push_back(temp); } moveCube(); return 0;}

0

백준 3190 - 뱀

https://www.acmicpc.net/problem/3190 체점 현황 전체 소스 코드#include <bits/stdc++.h>using namespace std;int board[110][110];int board_size;int num_of_apple;int num_of_command;map<int, char> command;// 동, 남, 서, 북int dx[4] = {1, 0, -1, 0};int dy[4] = {0, 1, 0, -1};int direction[4] = {0, 1, 2, 3};struct snake { int y; int x; int dir;};int main(void) { cin >> board_size >> num_of_apple; for (int i = 0; i < num_of_apple; i++) { int y, x; cin >> y >> x; board[y][x] = 1; } cin >> num_of_command; for (int i = 0; i < num_of_command; i++) { int time; char dir; cin >> time >> dir; command[time] = dir; } queue<pair<int, int>> snake_tail; int snake_head_y = 1; int snake_haed_x = 1; int snake_dir = 0; snake_tail.push({1, 1}); board[1][1] = 2; int time = 0; while (true) { time++; snake_head_y += dy[snake_dir]; snake_haed_x += dx[snake_dir]; snake_tail.push({snake_head_y, snake_haed_x}); if (board[snake_head_y][snake_haed_x] == 2) { cout << time << '\n'; return 0; } if (0 >= snake_head_y || snake_head_y > board_size || 0 >= snake_haed_x || snake_haed_x > board_size) { cout << time << '\n'; return 0; } if (board[snake_head_y][snake_haed_x] == 1) { board[snake_head_y][snake_haed_x] = 2; } else { board[snake_head_y][snake_haed_x] = 2; board[snake_tail.front().first][snake_tail.front().second] = 0; snake_tail.pop(); } if (command.find(time) != command.end()) { char com = command[time]; command.erase(time); if (com == 'L') { snake_dir = (snake_dir + 3) % 4; } else { snake_dir = (snake_dir + 1) % 4; } } } return 0;}

0

JPA - Entity의 생명주기

목차 JPA - Entity의 생명주기 JPA - Persist Context (영속성 컨텍스트) 엔티티 생명주기비영속 (new/transient) Entity 객체가 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태 Entity 객체가 생성돼 아직 영속성 컨텍스트에 저장되기 전 상태다. // 비영속 상태Member member = new Member();member.setId(101L);member.setName("HelloJPA"); 영속 (managed) Entity 객체가 현재 영속성 컨텍스트에 관리되는 상태

0

백준 1753 - 최단 경로

https://www.acmicpc.net/problem/1753 문제 해설가장 기본적이고 정형화된 다익스트라 문제이다! 다익스트라 알고리즘에서는 우선순위 큐를 사용하는데 기본적으로 우선순위 큐는 값이 큰 것부터 우선적으로 나가게 된다. #include <bits/stdc++.h>using namespace std;#define INF 987654321int V, E;int startPoint;int dist[20002]; // dist[x] : 시작점으로부터 점 x까지의 최단 거리를 저장한다.vector<vector<pair<int, int>>> graph;void dijkstra(int start) { // 초기값은 무한대로 설정해 놓는다. for (int i = 1; i < V + 1; i++) { dist[i] = INF; } priority_queue<pair<int, int>> pq; pq.push({0, start}); dist[start] = 0; while (!pq.empty()) { int cntDist = -pq.top().first; int cntVertex = pq.top().second; pq.pop(); // 현재 점까지의 거리와 저장된 최단거리를 비교한다. // 현재 점까지의 거리가 더 큰 경우는 나중에 최단거리가 갱신된 것이다. // 우리는 각 점에 최단거리로 간 상태에 대해서만 갱신을 진행하므로 밑의 연산은 진행하지 않는다. if (cntDist > dist[cntVertex]) { continue; } // 아래 로직을 대신 사용해도 결과는 똑같이 나온다. // 즉 현재 점까지의 거리가 최단거리까지와 일치하는지 확인하는 단계이다. // if (cntDist != dist[cntVertex]) { // continue; // } for (int i = 0; i < graph[cntVertex].size(); i++) { int nextVertex = graph[cntVertex][i].first; int weight = graph[cntVertex][i].second; // cntDist 대신 dist[cntVertex]를 사용해도 결과는 동일하다 // int nextDist = dist[cntVertex] + weight; int nextDist = cntDist + weight; if (dist[nextVertex] > nextDist) { dist[nextVertex] = nextDist; // 값을 음수로 저장해 우선순위가 반대가 되도록 한다. pq.push({-nextDist, nextVertex}); } } }}int main(void) { cin >> V >> E; cin >> startPoint; graph = vector<vector<pair<int, int>>>(V + 1); for (int i = 0; i < E; i++) { int a, b, weight; cin >> a >> b >> weight; graph[a].push_back({b, weight}); } dijkstra(startPoint); for (int i = 1; i <= V; i++) { if (dist[i] == INF) { cout << "INF" << '\n'; } else { cout << dist[i] << '\n'; } } return 0;} priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; 우선순위 큐에 greater<pair<int, int>>> pq 정렬 방식을 통해 값이 작은 것부터 우선적으로 나가게 된다. #include <iostream>#include <vector>#include <queue>using namespace std;#define INF 2000000000// 정점의 개수 : v, 간선의 개수 : eint v, e;vector<vector<pair<int, int>>> graph;vector<int> dist;vector<bool> check;int start_node;void dijkstra(){ for (int i = 1; i <= v; i++) dist[i] = INF; dist[start_node] = 0; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; pq.push({0, start_node}); while (!pq.empty()) { int weight = pq.top().first; int cnt_node = pq.top().second; pq.pop(); if (check[cnt_node] == true) continue; check[cnt_node] = true; // 점 cnt_node에 연결된 간선의 개수 int edge_num = graph[cnt_node].size(); for (int j = 0; j < edge_num; j++) { // from : 현재 위치, to : 다음 위치, from_to_weight : 현재위치에서 다음위치 까지의 가중치 int from = cnt_node, to = graph[cnt_node][j].first, from_to_weight = graph[cnt_node][j].second; if (dist[to] > dist[from] + from_to_weight) { dist[to] = dist[from] + from_to_weight; pq.push({dist[to], to}); } } }}int main(void){ scanf("%d %d %d", &v, &e, &start_node); dist = vector<int>(v + 1, INF); check = vector<bool>(v + 1, false); graph = vector<vector<pair<int, int>>>(v + 1); for (int i = 0; i < e; i++) { int from, to, weight; scanf("%d %d %d", &from, &to, &weight); graph[from].push_back({to, weight}); } dijkstra(); for (int i = 1; i <= v; i++) { if (dist[i] == INF) printf("INF\n"); else { printf("%d\n", dist[i]); } } return 0;}

0

Spring Boot 게시판 만들기 15 - Github와 jenkins 연동하기

15. Github와 jenkins 연동하기Github webhookngrok을 이용해 외부접근이 가능하도록 네트워크 열기Push 이벤트가 일어났을 때 로컬 Jenkins가 해당 훅을 받기 위해서는 해당 네트워크(포트)를 외부접근이 가능하게 열어놔야 한다.ngrok 프로그램을 사용해 Github로부터 hook을 받을 수 있도록 Jenkins 포트를 열어준다. ngrok은 local PC를 외부에서 접근이 가능하도록 열어주는 프로그램이다. Webhook 추가하기Project Repository > settings > Webhooks > add webhook 로 이동해 Payload URL에 http://[서버 IP주소]:[Port번호]/github-webhook/ 형식으로 날릴 주소를 기입하도록한다. 반드시 주소 뒤에 /github-webhook/ 를 추가해야 한다. Push가 일어났을 때 Payload URL(Jenkins)로 Hook을 날린다.

0

Spring Boot 게시판 만들기 16 - Github와 jenkins 연동하기

16. Github와 jenkins 연동하기Github webhookngrok을 이용해 외부접근이 가능하도록 네트워크 열기Push 이벤트가 일어났을 때 로컬 Jenkins가 해당 훅을 받기 위해서는 해당 네트워크(포트)를 외부접근이 가능하게 열어놔야 한다.ngrok 프로그램을 사용해 Github로부터 hook을 받을 수 있도록 Jenkins 포트를 열어준다. ngrok은 local PC를 외부에서 접근이 가능하도록 열어주는 프로그램이다. Webhook 추가하기Project Repository > settings > Webhooks > add webhook 로 이동해 Payload URL에 http://[서버 IP주소]:[Port번호]/github-webhook/ 형식으로 날릴 주소를 기입하도록한다. 반드시 주소 뒤에 /github-webhook/ 를 추가해야 한다. Push가 일어났을 때 Payload URL(Jenkins)로 Hook을 날린다.