本田等日本大型企业拟测试高速行驶时为电动汽车充电的系统
Readhub
包括本田在内的日本多家大型企业决定于明年开展高速公路行驶状态下电动汽车充电系统的技术验证测试。
Score: 57.25Confidence: 54%
View offerLoading the catalog…
THE AI OPPORTUNITY INDEX
Find your next AI tool. Explore free access, trials, and credits — all in one place.
Readhub
包括本田在内的日本多家大型企业决定于明年开展高速公路行驶状态下电动汽车充电系统的技术验证测试。
Score: 57.25Confidence: 54%
View offervelog
문제 문자열 겹쳐쓰기 문제 설명 문자열 my_string , overwrite_string 과 정수 s 가 주어집니다. 문자열 my_string 의 인덱스 s 부터 overwrite_string 의 길이만큼을 문자열 overwrite_string 으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요. 제한사항 my_string 와 overwrite_string 은 숫자와 알파벳으로 이루어져 있습니다. $1 \leq$ overwrite_string 의 길이 $\leq$ my_string 의 길이 $\leq 1,000$ $0 \leq$ s $\leq$ my_string 의 길이 $-$ overwrite_string 의 길이 입출력 예시 |my_string|overwrite_string|s|result| |-|-| |"He11oWor1d"|"lloWorl"|2|"HelloWorld"| |"Program29b8UYP"|"merS123"|7|"ProgrammerS123"| 문제 풀이 s 부터 overwrite_string 는 결국 overwrite_string 이 되기 때문에 s 까지는 my_string 으로 하고 overwrite_string 을 넣고 s 부터 overwrite_string 이후에 다시 my_string 이 가면 됨. 첫 번째 예시를 보면 my_string[:2] = He overwrite_string = lloWorl overwrite_string 의 길이 = 7 $2 + 7 = 9$ 이므로 my_string[9:] = d my_string[:2] + overwrite_string + my_string[9:] = He + lloWorl + d = HelloWorld def solution(my_string, overwrite_string, s): length = len(overwrite_string) return my_string[:s] + overwrite_string + my_string[s + length:]
Score: 54.4Confidence: 49%
View offervelog
A healthy lawn can make an outdoor property more attractive, functional, and comfortable. However, creating a dense lawn requires more than placing grass over bare soil. Soil preparation, grading, soil drainage , grass selection, installation technique, watering, and follow-up care all influence how successfully new turf becomes established. For property owners researching Best Sod Installation Services in Alpharetta, GA, understanding the complete installation process can make it easier to plan a lawn improvement project. Sod provides an established layer of grass that can create a finished appearance much faster than starting a lawn entirely from seed, but the underlying soil and early maintenance still play important roles. Why Do Property Owners Choose Sod? Sod can be useful when a property owner wants to establish a lawn without waiting for grass seed to germinate and gradually fill an area. Rolls or sections of living turf are installed across prepared soil, creating a relatively immediate lawn surface. This approach can be considered for several situations. A newly constructed property may have bare soil, an existing lawn may have extensive thin or damaged areas, or a homeowner may want to replace an unsuccessful lawn. Sod can also provide more predictable initial coverage than scattered seed. However, installation should not be viewed as simply placing grass on top of the ground. The condition of the soil underneath remains important to long-term lawn health. What Should Be Evaluated Before Sod Installation? The first step should be evaluating the property. Different yards can have different amounts of sunlight, soil conditions, slopes, drainage patterns, and existing vegetation. A site assessment can identify areas that may require additional preparation before sod is installed. Important considerations include: • Existing grass or weeds • Soil condition • Compaction • Drainage • Property slope • Sunlight exposure • Irrigation access • Walkways and hardscapes • Trees and existing landscape features • Type of grass appropriate for the site Understanding these factors helps prevent problems that might otherwise appear after installation. Why Is Soil Preparation So Important? Sod needs contact with suitable soil so its roots can begin growing into the ground. If the underlying soil is heavily compacted, uneven, excessively dry, or poorly drained, the new turf may struggle to establish. Preparation can involve removing unwanted vegetation, loosening compacted soil, correcting low or uneven areas, and incorporating suitable soil amendments when necessary. The objective is to create a reasonably level and supportive growing surface. Soil preparation should be based on the actual condition of the property rather than applying the same process to every yard. A prepared soil surface can also make installation easier because sod sections can sit more evenly and maintain better contact with the ground. How Does Grading Affect a New Lawn? Grading influences how water moves across a property. Poor grading can leave some areas excessively wet while other sections become too dry. Before installing sod, property owners should look for areas where rainwater collects or flows toward structures. Low spots may require correction, while slopes may need careful consideration to reduce erosion. A lawn does not necessarily need to be perfectly flat. The important consideration is whether the finished grade supports appropriate drainage and creates a practical surface for mowing and everyday use. Correct grading can also help the finished lawn transition smoothly into driveways, walkways, planting beds, and other landscape features. Which Sod Type Should Be Selected? Choosing the right grass is one of the most important decisions in a sod project. Different turf varieties have different requirements for sunlight, water, temperature, maintenance, and traffic. Warm-season grasses commonly considered for Georgia properties include Bermuda and Zoysia. Tall Fescue may be considered for locations with greater shade tolerance requirements, depending on site conditions and the property owner's goals. Bermuda generally performs well in sunny conditions and can tolerate substantial activity when properly maintained. Zoysia can provide dense turf and may offer greater tolerance of partial shade than some warm-season alternatives. Fescue has different growth characteristics and is often considered where shade is a significant factor. The correct choice should depend on the actual conditions of the yard rather than simply selecting the most popular grass. Why Does Sunlight Matter? Grass requires appropriate light to maintain healthy growth. A lawn beneath mature trees may receive considerably less direct sunlight than an open front yard. Before choosing sod, property owners should observe how sunlight changes throughout the day and across different seasons. If a grass variety requires more sunlight than the property provides, thinning or weak growth may develop over time. Shade can also change as trees mature. Therefore, a planting and lawn plan should consider both current and future conditions. How Is Sod Installed? Once the site has been prepared and the appropriate sod has been selected, installation can begin. Sod sections should be placed closely together without creating large gaps between pieces. Seams should be arranged carefully so the edges do not form continuous lines across the lawn. Sod may need to be trimmed around trees, planting beds, sidewalks, irrigation features, and other obstacles. The turf should maintain good contact with the prepared soil. Rolling may be used after installation to improve contact and reduce air pockets. The finished surface should then receive appropriate initial watering according to the grass type, weather, soil condition, and installation circumstances. How Important Is Watering After Installation? Watering is one of the most important parts of early sod establishment. Newly installed turf has not yet developed an extensive root system within the underlying soil. The objective is to keep the root zone adequately moist without creating prolonged saturation. Watering needs can change according to temperature, rainfall, soil type, grass variety, and exposure to sunlight. A newly installed lawn may require more frequent attention during its establishment period than an established lawn. Property owners should monitor the soil and turf instead of relying on a fixed schedule regardless of weather. Too little water can cause drying and stress, while excessive watering can contribute to drainage and root problems. When Can New Sod Be Mowed? Mowing should generally wait until the new grass has developed sufficient roots to remain firmly established. Walking repeatedly across freshly installed sod can disturb the pieces before they have rooted properly. Similarly, mowing too early may pull or shift sections of turf. The appropriate timing depends on the grass type, weather, installation conditions, and rate of establishment. When mowing begins, the mower should be properly maintained and the cutting height should be appropriate for the selected turf variety. What Maintenance Does New Sod Need? Sod installation is the beginning of lawn care rather than the end. After establishment, the lawn may require regular mowing, watering, fertilization, weed management, aeration, and observation for potential pest or disease problems. Maintenance requirements vary by grass type. Warm-season turf typically follows a different growth cycle from cool-season turf. Property owners should also monitor areas around trees and structures because shade, root competition, and drainage changes can influence lawn performance. Consistent maintenance is generally more effective than waiting until the lawn develops significant problems. What Are Common Sod Installation Mistakes? Several mistakes can reduce the success of a new lawn. One common mistake is skipping soil preparation. Even high-quality sod may struggle when installed over compacted or unsuitable soil. Another mistake is selecting grass based only on appearance. A visually attractive turf variety may not perform well in a heavily shaded or poorly drained location. Improper grading can create standing water or uneven surfaces. Incorrect watering can also stress newly installed turf. Installing sod with large gaps between sections can leave visible seams and allow weeds to develop between pieces. Finally, excessive foot traffic immediately after installation can disturb the turf before roots become established. How Can Property Owners Prepare for Installation? Preparation can make the installation process more efficient. Property owners can remove movable outdoor furniture, identify irrigation components, and discuss drainage concerns before work begins. If an existing lawn is being replaced, unwanted vegetation may need to be removed. Trees, landscape beds, fences, and walkways should also be identified so the installation plan accounts for them. Property owners should also consider how the finished lawn will be used. A yard intended for children, pets, entertaining, or frequent foot traffic may require different turf considerations from a primarily decorative lawn. Should Existing Drainage Problems Be Fixed First? Yes, drainage deserves attention before installing new sod. Best Sod Installation Services in Alpharetta, GA can help property owners consider site conditions and identify whether drainage issues should be addressed before new turf is installed. If water consistently collects in certain areas, simply covering the ground with new turf may not solve the underlying problem. Drainage concerns can result from grading, compacted soil, downspout discharge, landscape features, or natural site conditions. Addressing the source of recurring water problems before installation can help protect the investment in new turf. How Can Sod Improve an Existing Landscape? A new l
Score: 54.4Confidence: 49%
View offervelog
缅甸果敢老街🇲🇲 华纳国际『圣淘沙』 🎞赌场直播: 网投现场同步 🎞手机下载App与现场真人玩家同步下注 💯24小时接受视频验证现场。 💯24小时可充值提现 充值接受:微信、支付宝、网银转账、缅币KBZ 、USDT 📢📢📢📢📢📢📢📢📢📢 联系方式 飞机✈️: @stszh223 圣淘沙官网: 235838.com pg注册网址: 235838.com
Score: 54.4Confidence: 49%
View offervelog
The global shipping industry is an important part of international trade, transporting goods between countries and connecting businesses across the world. As the industry continues to grow, environmental sustainability has become an increasingly important consideration. Brian Ladin has discussed how shipping companies can adopt more efficient practices and technologies to reduce their environmental impact. Environmental Sustainability in the Modern Shipping Industr One important area of focus is improving vessel efficiency. Modern ship designs, improved hull structures, better propulsion systems, and regular maintenance can help reduce fuel consumption. Using less fuel can lower operating costs while also reducing emissions from commercial vessels. Another approach is slow steaming, which involves operating vessels at lower speeds to reduce fuel consumption and emissions during long-distance voyages. Although slower speeds may require changes to transportation schedules, they can provide an effective way for shipping companies to improve overall fuel efficiency. Become a Medium member The development of cleaner marine fuels is also becoming increasingly important. LNG has been explored as an alternative fuel for certain vessels, while the industry continues to investigate other low-carbon and renewable fuel options. These developments could play an important role in reducing the environmental impact of maritime transportation. Technology can also support more sustainable shipping operations. Digital monitoring systems can help operators track fuel consumption, vessel performance, and voyage efficiency. Better data allows shipping companies to identify areas where energy can be saved and operations can be improved. Sustainability also extends beyond the vessels themselves. More efficient supply-chain planning can help reduce unnecessary journeys and improve the movement of containers. Reducing empty container transportation can save fuel and make global shipping operations more efficient. According to discussions by Brian Ladin, environmental responsibility and business efficiency can work together. Many improvements that reduce fuel consumption can also help shipping companies lower operating expenses and improve their long-term performance. As environmental standards continue to develop, shipping companies are likely to invest further in cleaner fuels, efficient vessels, digital technologies, and improved operational practices. These changes can help the maritime industry respond to environmental challenges while continuing to support international trade. Brian Ladin’s views highlight the growing importance of combining innovation, efficiency, and environmental responsibility in modern shipping. With continued investment and technological development, the global shipping industry can work toward a more sustainable and efficient future. Brian Ladin
velog
🎯 핵심 키워드 키워드 내용 API Gateway 클라이언트의 요청을 받아 라우팅, 인증, 권한 부여, 부하 분산(Load Balancing), 로깅 등 공통 기능(횡단 관심사)을 수행하는 최전방 프록시 서버 Spring Cloud Gateway Spring 진영의 비동기 (Non-blocking) 방식 게이트웨이 WebFlux 기반으로 적은 스레드로 많은 요청을 처리할 수 있다. Route / Predicate / Filter - Route : 목적지 URL(uri) 설정 - Predicate : 조건식 ( ex. Path=/first-service/** ) - Filter : 요청/응답을 가로채어 조작(Header 추가, 인증, 로깅 등)하는 컴포넌트 Load Balancing (lb://) 유레카(Eureka)에 등록된 다수의 서비스 인스턴스(서버) 중 트래픽을 분산시켜 주는 기능 📖 오늘 배운 내용 1. API Gateway 동작 및 Filter 흐름 분석 API Gateway 역할 ↓ Spring Cloud Gateway ↓ Route / Predicate ↓ Request / Response Filter ↓ Custom Filter ↓ Global Filter ↓ Eureka 연동 ↓ Service Name 기반 Routing ↓ Load Balancing [Filter 동작 순서 상세 (Pre & Post)] 게이트웨이는 비즈니스 로직(마이크로서비스)을 호출하기 전/후에 필터를 거친다. Request(요청) 방향 (Pre Filter) : Client ➔ Global Pre ➔ Custom Pre ➔ Logging Pre ➔ Business Logic(Microservice) Response(응답) 방향 (Post Filter) : Business Logic ➔ Logging Post ➔ Custom Post ➔ Global Post ➔ Client 2. Spring Cloud Gateway 설정 및 유레카 연동 (apigateway-service) 게이트웨이 자체도 유레카 클라이언트로 등록되어야 하며, 들어오는 요청을 lb:// 프로토콜을 통해 유레카에 등록된 서비스 이름(Service Name)으로 라우팅해야 로드 밸런싱이 동작한다 [application.yml 설정] server: port: 8000 # 게이트웨이는 고정 포트(8000) 사용 eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:8761/eureka instance: prefer-ip-address: true # 호스트명 대신 IP로 등록 spring: application: name: apigateway-service cloud: gateway: default-filters: # Global Filter 설정 (모든 라우트에 공통 적용) - name: GlobalFilter args: baseMessage: Spring Cloud Gateway Webflux Global Filter preLogger: true postLogger: true routes: - id: first-service # uri: http://localhost:8081/ (직접 호출 방식은 주석 처리) uri: lb://MY-FIRST-SERVICE # 유레카 연동: lb://서비스이름 (로드 밸런싱) predicates: - Path=/first-service/** filters: - CustomFilter - id: second-service uri: lb://MY-SECOND-SERVICE predicates: - Path=/second-service/** filters: - name: CustomFilter - name: LoggingFilter # Logging Filter 추가 args: baseMessage: Hi, there. preLogger: true postLogger: true 3. Filter 구현 (Global, Custom, Logging) Spring Cloud Gateway의 필터는 AbstractGatewayFilterFactory를 상속받아 구현한다. * 1. Global Filter * 모든 라우팅에 기본적으로 적용되는 필터 @Component @Slf4j public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> { // ... 생성자 생략 ... @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); // Custom Pre Filter: 인증 검사, 헤더추가, 로깅 등을 여기서 처리 log.info("Global Filter baseMessage: {}, {}", config.getBaseMessage(), request.getRemoteAddress()); if (config.isPreLogger()) { log.info("Global Filter Start: request id -> {}", request.getId()); } // Custom Post Filter: 체인이 끝난 후 비동기로 실행 return chain.filter(exchange).then(Mono.fromRunnable(() -> { if (config.isPostLogger()) { log.info("Global Filter End: response code -> {}", response.getStatusCode()); } })); }; } // ... Config 클래스 생략 ... } 2. Logging Filter와 우선순위(Ordered) 특정 라우트에만 적용되는 필터이며, OrderedGatewayFilter를 사용해 필터의 실행 순서를 강제로 지정할 수 있다 @Component @Slf4j public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> { // ... 생략 ... /* 우선 순위를 갖는 Logging Filter 적용 */ @Override public GatewayFilter apply(Config config) { OrderedGatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> { // ... (Pre/Post 로깅 로직은 Global Filter와 유사) ... return chain.filter(exchange).then(Mono.fromRunnable(() -> { if (config.isPostLogger()) { log.info("Logging Filter End: response code -> {}", response.getStatusCode()); } })); }, Ordered.HIGHEST_PRECEDENCE); // 가장 먼저(Highest) 실행되도록 우선순위 강제 조정 return filter; } } 4. Microservice 연동 및 Load Balancing 테스트 First Service와 Second Service를 각각 여러 대(포트 0 랜덤) 띄운 후, http://localhost:8000 (gateway) 를 통해 요청을 보냈을 때 로드 밸런싱이 되는지 확인했다 [Microservice application.yml] server: port: 0 # 랜덤 포트 설정 spring: application: name: my-second-service # 유레카에 등록될 서비스명 (게이트웨이의 lb:// 주소와 매칭됨) eureka: instance: # 고유 식별자를 부여하여 다중 인스턴스가 유레카에 개별적으로 등록되게 함 instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${random.value}} [테스트 결과] Postman을 이용해 GET http://localhost:8000/first-service/check 형식으로 Gateway에 요청을 여러 번 보내면, 게이트웨이가 유레카에서 서비스 인스턴스 목록을 받아와 라운드 로빈(Round Robin) 방식 으로 포트를 번갈아가며(ex: 52887 ➔ 52888) 응답하는 것을 확인할 수 있었다. 이는 Gateway와 Eureka를 통한 완벽한 로드 밸런싱이 수행됨을 의미한다
velog
작은 주문 조회 서비스가 새 버전으로 배포됐다고 가정해 보겠습니다. 화면은 열리고 주문 번호도 조회됩니다. 담당자는 이어서 로그인 경로, 파일 접근 권한, 통신 규칙, 감사 기록과 복구 준비를 확인합니다. 이 결과를 한곳에 모으면 이번 변경에서 무엇을 확인했는지 설명할 수 있습니다. AWS는 서버와 저장소 등을 제공하는 클라우드 서비스입니다. Hardening은 공격과 실수에 견디도록 설정과 운영 절차를 강화하는 과정입니다. 이번 글은 AWS Hardening 15편의 마무리입니다. 앞선 글에서 다룬 보호 조건을 서비스 하나의 점검 흐름으로 연결합니다. 맡은 범위를 먼저 적습니다 AWS와 사용자는 보안의 책임을 나눠 맡습니다. 선택한 서비스에 따라 사용자가 관리할 범위가 달라집니다. EC2 같은 가상 서버에서는 설치한 운영체제와 애플리케이션, 통신 설정을 관리합니다. S3 같은 파일 저장 서비스에서도 데이터와 접근 권한의 관리가 필요합니다. AWS Shared Responsibility Model 점검 대상에는 서비스 이름, AWS 계정, Region, 사용한 자원과 담당자를 적습니다. Region은 AWS 서비스를 사용하는 지역 단위입니다. Resource는 서버나 저장소처럼 AWS에서 관리하는 대상을 뜻합니다. 한 지역의 검사 결과를 다른 지역에도 적용하려면 그곳의 설정과 동작을 확인해야 합니다. 여기서는 설명용 서비스 study-orders 를 사용합니다. 실제 계정 정보와 고객 데이터는 사용하지 않습니다. 사용자는 주문을 조회하고, 애플리케이션은 필요한 파일을 읽고, 운영자는 배포와 복구를 담당한다고 가정합니다. 이 세 주체가 필요한 작업을 각각 정하면 검사할 경계도 구체적으로 고를 수 있습니다. 1편부터 10편까지의 설정을 동작으로 확인합니다 로그인과 권한 1편에서는 MFA와 임시 자격 증명을 다뤘습니다. MFA는 로그인할 때 추가 인증을 요구하는 방식입니다. 임시 자격 증명에는 사용할 수 있는 시간이 정해집니다. 실제 로그인에서 추가 인증이 요구되는지, 역할을 맡은 뒤 필요한 조회가 가능한지, 정한 세션 처리 조건이 적용되는지 확인합니다. 세션은 발급받은 자격 증명으로 작업하는 기간입니다. 2편의 IAM은 누가 어떤 작업을 할 수 있는지 관리합니다. Role은 작업 권한을 담는 역할입니다. Trust Policy는 그 역할을 맡을 주체를 정하고 Permission Policy는 수행할 작업을 정합니다. 주문 조회 역할의 필요한 읽기 요청과 제한한 삭제 요청을 따로 확인합니다. 대상 자원에 연결된 정책도 함께 살펴봅니다. 네트워크와 서버 관리 3편에서는 VPC, Subnet과 Security Group을 살펴봤습니다. VPC는 AWS 안에서 사용하는 가상 네트워크이고, Subnet은 그 안에서 나눈 구역입니다. Security Group은 허용할 통신을 정합니다. 주문 조회 애플리케이션에서 데이터베이스로 연결되는 경로와 제한한 출처의 연결 결과를 함께 기록합니다. 4편에서는 EC2의 관리 연결과 IMDSv2를 구분했습니다. EC2는 가상 서버입니다. IMDSv2는 서버가 자신의 정보와 역할 자격 증명에 접근할 때 사용하는 경로입니다. 먼저 세션 Token을 발급받고 그 값으로 정보를 요청합니다. Token은 요청에 함께 보내는 값입니다. 운영자의 관리 접속이 정상 동작하는지, 애플리케이션의 정보 요청이 이 조건에서 동작하는지 확인합니다. 설치한 운영체제와 애플리케이션의 보안 업데이트도 해당 담당자가 관리합니다. 데이터와 실행 주체 5편의 S3에서는 파일의 공개 접근, 객체 소유권, 전송 보호를 확인했습니다. Bucket은 파일을 담는 저장 공간이고 객체는 그 안의 파일 단위입니다. 주문 보고서가 필요한 역할에만 제공되는지, 정한 보호 조건으로 파일을 주고받는지 확인합니다. 6편에서는 Secrets Manager와 KMS를 연결했습니다. Secrets Manager는 비밀번호 같은 비밀을 저장하고 KMS는 암호화 Key를 관리합니다. KMS Key는 암호화 작업과 사용 권한을 관리하는 자원입니다. 비밀을 읽는 권한과 복호화 권한을 확인합니다. 복호화는 암호화된 내용을 다시 읽을 수 있게 하는 과정입니다. 비밀번호를 교체했다면 기존 연결과 새 연결의 결과도 살펴봅니다. 8편의 RDS에서는 데이터베이스 접속, 전송 보호와 복원 조건을 확인했습니다. RDS는 데이터베이스 운영을 돕는 서비스입니다. 별도 시험 환경에서 데이터를 복원하고 내용, 연결 권한과 서비스 조회를 검사합니다. 암호화 Key의 유지와 사용 권한도 복구 계획에 넣습니다. 9편의 EKS에서는 애플리케이션의 AWS 권한과 운영자의 Cluster 접근을 나눴습니다. Kubernetes는 컨테이너 애플리케이션을 배치하고 관리하는 도구입니다. 컨테이너는 프로그램을 실행하는 격리된 환경입니다. EKS는 Kubernetes를 운영하는 서비스이고 Cluster는 함께 구성된 서버와 관리 요소의 묶음입니다. 애플리케이션이 필요한 AWS 작업을 수행하는지, 운영자는 승인한 경로에서 관리 요청을 수행하는지 각각 확인합니다. 기록과 조직 규칙 7편의 CloudTrail은 AWS 활동 기록을 다룹니다. GuardDuty는 의심스러운 활동의 탐지 결과를 제공합니다. 점검에서는 필요한 종류의 기록이 보관되는지, 경고가 담당자에게 전달되는지, 기록 조회와 후속 조치가 이어지는지 살펴봅니다. 10편에서는 Organizations의 SCP와 설정 점검을 연결했습니다. Organizations는 여러 계정을 묶어 관리합니다. SCP는 적용 대상 계정의 권한 상한을 제한하는 규칙입니다. 실제 작업에는 필요한 IAM 권한도 있어야 합니다. AWS Config는 자원 설정을 기록하고 정한 기준에 맞는지 평가합니다. Security Hub CSPM은 보안 설정을 점검하고 결과를 모아 보여 줍니다. 점검 결과는 대상 계정, Region, 수집 범위와 함께 읽습니다. 예외에는 담당자, 이유와 재검토 조건을 적습니다. 11편부터 14편까지 운영 과정에 연결합니다 11편에서는 IAM Access Analyzer의 결과를 읽고 접근 권한을 다시 검토했습니다. Analyzer는 정한 범위에서 접근을 분석하는 도구입니다. 결과에 나온 공유가 업무상 필요한지 확인하고, 정책 변경 뒤의 분석 결과와 실제 업무 요청을 기록합니다. 주기적으로 실행하는 작업도 사용 기간에 포함해 검토합니다. 12편에서는 AWS Backup의 보존 조건과 복원 시험을 연결했습니다. Backup은 복구에 사용할 사본을 관리하는 작업입니다. 보존 기간과 삭제 보호 조건을 검토하고, 복원한 데이터와 애플리케이션의 결과를 따로 확인합니다. 복원 시험의 판정과 시험 자원의 정리 상태까지 기록합니다. 13편에서는 CloudFormation의 Drift와 Change Set을 다뤘습니다. CloudFormation은 설정 파일로 AWS 자원을 관리합니다. Drift는 설정 파일과 실제 자원 사이의 차이이고, Change Set은 실행할 변경 내용을 검토하는 목록입니다. 바뀔 속성, 자원 교체 여부와 복구 계획을 확인하고 승인된 범위에서 변경 결과를 검사합니다. 14편에서는 합성 사건 기록으로 Incident Drill의 대응 순서를 검사했습니다. Incident Drill은 사고 상황을 가정해 대응 흐름을 점검하는 활동입니다. 조사 기록을 보존하고 조치 범위를 승인받습니다. 필요한 제한을 적용한 뒤 서비스와 데이터의 복구 결과를 확인합니다. 연습에서 발견한 빠진 단계에는 담당자와 다음 점검 조건을 남깁니다. 한 번의 변경에 다섯 단계의 증거를 남깁니다 대상과 담당자 정하기 → 접근과 통신 확인 → 데이터와 기록 확인 → 변경과 복구 검사 → 결과와 다음 점검 남기기 그림은 서비스 변경을 검토할 때 사용할 운영 절차의 제안입니다. 각 단계의 실행과 연결은 해당 환경에 맞게 준비합니다. 실제 결과도 그 환경에서 얻습니다. 확인할 항목이 남아 있으면 담당자와 추가 확인 조건을 기록합니다. 질문 남길 결과 누가 어떤 작업을 하나요? 주체, 대상, 필요한 요청의 성공과 제한 요청의 거절 어느 경로로 연결하나요? 허용한 출처의 연결과 제한한 출처의 결과 데이터와 기록을 어떻게 지키나요? 접근 범위, 수집 대상과 실제 보관 결과 변경 실패 때 어떻게 복구하나요? 복구할 설정과 데이터, 실제 조회 결과와 소요 시간 언제 다시 확인하나요? 담당자, 다음 검토일과 변경 시 재검토할 조건 예를 들어 주문 조회는 성공했는데 새 백업에서 주문 한 건이 누락됐다고 가정해 보겠습니다. 점검 기록에는 조회 성공과 데이터 누락을 함께 적습니다. 복구 항목은 확인이 더 필요한 상태로 남깁니다. 같은 화면에 결과가 모여 있어도 각 결과의 대상과 확인 조건을 읽어야 합니다. 합성 기록에서 확인이 필요한 항목을 골라 봅니다 JavaScript는 프로그램의 동작을 적는 언어이고 Node는 이 코드를 실행하는 도구입니다. 아래 코드는 실제 AWS에 접속하지 않는 로컬 예제입니다. 필수 항목마다 담당자와 증거 표시가 정확히 한 개 있는지 검사합니다. 기록이 빠지거나 중복되면 해당 항목을 보류합니다. READY는 이 기록 형식이 채워졌다는 뜻이고 HOLD는 추가 확인할 기록이 있다는 뜻입니다. const expected = ["access", "network", "data", "audit", "recovery"]; const rows = expected.map((id) => ({ id, owner: "study-team", evidence: id === "recovery" ? "" : "synthetic-result", })); function review(records) { const pending = expected.filter((id) => { const matches = records.filter((row) => row.id === id); return ( matches.length !== 1 || typeof matches[0].owner !== "string" || !matches[0].owner.trim() || typeof matches[0].evidence !== "string" || !matches[0].evidence.trim() ); }); return { state: pending.length ? "HOLD" : "READY", pending }; } console.log(JSON.stringify(review(rows))); const complete = rows.map((row) => ({ ...row, evidence: "synthetic-result", })); console.log(JSON.stringify(review(complete))); Node v24.13.1에서 실행한 출력은 다음과 같습니다. {"state":"HOLD","pending":["recovery"]} {"state":"READY","pending":[]} 첫 입력에는 recovery의 증거 표시가 비어 있습니다. 함수는 복구 기록에 추가 확인이 필요하다고 표시합니다. 다음 입력에서는 합성 증거 표시를 채웠으므로 READY가 나옵니다. 누락, 중복, 공백 담당자와 공백 증거 표시를 넣은 추가 입력에서도 보류 판정을 확인했습니다. 이 예제는 입력 기록을 검사합니다. 실제 IAM 권한, 네트워크 통신, 데이터 복원과 로그 전달은 실행하지 않았습니다. 증거 표시의 문자열은 기록 유무를 나타냅니다. 운영 점검에서는 사용한 요청, 대상, 시각, 기대 결과와 실제 결과를 담당자가 확인해야 합니다. 바뀐 조건에서 다시 검토합니다 AWS의 보안 점검 가이드는 정기 검토와 함께 조직 구성, 사용 서비스와 애플리케이션이 바뀌는 상황의 재검토를 설명합니다. 접근이 의심되는 상황에서도 관련 설정을 살펴봅니다. 점검표에는 정기 일정과 변경 시 다시 볼 항목을 함께 남길 수 있습니다. AWS security audit guidelines 점검 결과를 기록할 때는 비밀번호, 자격 증명과 고객 정보의 원문을 제외합니다. 필요한 요약과 승인된 증거 위치를 남기고 기록을 읽을 권한도 정합니다. 담당자가 바뀌면 다음 담당자가 같은 범위와 결과를 따라갈 수 있는지 확인합니다. AWS Hardening 전체 목록 [AWS Hardening 01] 관리자 Login부터 줄이기: MFA와 임시 자격 증명 [AWS Hardening 02] 역할을 맡을 수 있는 사람과 할 수 있는 작업: IAM 최소 권한 [AWS Hardening 03] 같은 VPC니까 안전할까요? 보안 Group과 Subnet 경계 [AWS Hardening 04] SSH를 열기 전에: EC2 관리 경로와 IMDSv2 [AWS Hardening 05] 암호화된 Bucket도 공개될 수 있습니다: S3 접근 경계 [AWS Hardening 06] 비밀을 저장했는데도 읽을 수 있나요? KMS와 Secrets Manager [AWS Hardening 07] 경고를 켰는데 누가 볼까요? CloudTrail 감사와 대응 경로 [AWS Hardening 08] RDS를 비공개로 만들면 끝일까요? 연결 보호와 복원 검증 [AWS Hardening 09] EKS의 두 권한 경계: Pod의 AWS 접근과 API Server 접근 [AWS Hardening 10] 한 번 설정하고 끝내지 않기: SCP와 지속적인 보안 점검 [AWS Hardening 11] IAM Access Analyzer로 접근 권한을 다시 확인하기 [AWS Hardening 12] AWS Backup으로 보존과 복원 시험 연결하기 [AWS Hardening 13] CloudFormation 변경 전에 Drift와 영향 확인하기 [AWS Hardening 14] Incident Drill에서 조사와 복구를 연습하기 [AWS Hardening 15] 접근부터 복구까지, AWS 점검 흐름 완성하기 — 현재 글 확인 문제와 해설 S3 파일의 암호화 설정을 확인했습니다. 주문 보고서의 접근 경계를 확인하려면 어떤 결과가 더 필요할까요? CloudFormation의 변경 목록을 읽었습니다. 변경 완료를 확인할 때 무엇을 이어서 검사할까요? 합성 함수에서 READY가 나왔습니다. 실제 복구 성공을 기록하려면 어떤 증거가 필요할까요? 해설 필요한 역할의 읽기 성공과 제한한 역할의 거절 결과를 확인합니다. 관련 정책과 실제 요청 조건을 함께 남깁니다. 저장 암호화와 접근 권한은 각각 확인합니다. 실제로 실행한 변경의 결과와 서비스 동작을 검사합니다. 영향받은 권한과 통신 경로도 살펴보고, 데이터 이전이 있었다면 내용과 복구 조건을 확인합니다. 선택한 복구 지점, 복원 대상, 데이터 내용, 애플리케이션 조회, 접근 조건과 걸린 시간을 남깁니다. READY는 사람이 넣은 기록의 형식 판정입니다. 복습과 마무리 지금은 익숙한 서비스 하나에 다섯 질문을 적용해 기대 결과를 적어 보세요. 하루 뒤에는 증거 한 개가 빠진 상황을 가정하고 담당자와 추가 확인 조건을 써 보세요. 일주일 뒤에는 역할, Region 또는 백업 구성이 바뀐 상황에서 다시 검사할 항목을 골라 보세요. 이 일정은 복습 제안입니다. AWS Hardening 15편은 로그인과 권한에서 시작해 네트워크, 데이터, 기록, 조직 규칙, 변경 검증과 복구로 이어졌습니다. 마무리에 남길 것은 확인한 범위와 결과를 다시 읽을 수 있는 기록입니다. 다음 변경에서도 같은 질문을 사용하고, 달라진 조건에 필요한 검사를 이어갑니다. 공식 문서 검토일: 2026-10-06. 점검 흐름과 합성 기록 예제는 이 시리즈를 연결하기 위해 작성했습니다.
velog
华纳国际-孟波圣淘沙 主营: 百家乐 ,龙虎, 牛牛 炸金花,大小,单双,推筒子 充值 上下方充值方式 网银👉支付宝👉微信 缅币 USDT 等方式。 百家乐网址: 235838.com PG电子网址: 235838.com 开户客服TG: @stszh223 全球不限IP,随时随地畅玩! 免实名,无需绑卡手机号!信息安全保障! U存U取,每日提款不限次数,不限额度! 大额出款无忧!东南亚盘总大客首选平台!
Score: 54.4Confidence: 49%
View offervelog
Spring 핵심 개념 정리 1. Bean 수동 등록 Spring에서 객체를 Bean으로 등록하는 방법에는 크게 컴포넌트 스캔을 이용한 자동 등록 과 @Bean 을 이용한 수동 등록 이 있다. 수동 등록 대표적으로 직접 생성하기 어려운 객체나 라이브러리 객체를 Bean으로 등록할 때 사용한다. @Configuration public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } 이렇게 등록하면 Spring Container가 PasswordEncoder 객체를 관리한다. BCryptPasswordEncoder 비밀번호를 저장할 때 평문 그대로 저장하면 보안상 위험하다. 평문 비밀번호 password123 이를 BCrypt로 해싱하면 다음과 같이 알아볼 수 없는 값으로 저장된다. $2a$10$... 정확히 말하면 BCrypt는 일반적인 의미의 "암호화(Encryption)"보다는 단방향 해시(Hashing) 에 가깝다. 따라서 사용자가 로그인할 때는 입력받은 비밀번호를 다시 BCrypt 방식으로 검증하여 DB에 저장된 해시와 일치하는지 확인한다. 2. 같은 타입의 Bean이 여러 개 존재하는 경우 Spring에서 같은 타입의 Bean이 여러 개 등록되어 있으면 어떤 Bean을 주입해야 하는지 결정할 수 없는 문제가 발생할 수 있다. 예를 들어: @Bean public PasswordEncoder encoder1() { return new BCryptPasswordEncoder(); } @Bean public PasswordEncoder encoder2() { return new BCryptPasswordEncoder(); } PasswordEncoder 타입의 Bean이 2개 존재한다. @Autowired private PasswordEncoder passwordEncoder; 이 경우 Spring 입장에서는 PasswordEncoder가 2개인데 어떤 것을 주입해야 하지? 라는 문제가 발생한다. 해결 방법 1. @Qualifier 특정 Bean을 명시적으로 지정한다. @Autowired @Qualifier("encoder1") private PasswordEncoder passwordEncoder; 해결 방법 2. @Primary 기본적으로 사용할 Bean을 지정한다. @Bean @Primary public PasswordEncoder encoder1() { return new BCryptPasswordEncoder(); } 이후 별도의 지정이 없다면 encoder1 이 우선적으로 선택된다. Qualifier와 Primary가 동시에 존재한다면? @Qualifier 가 더 높은 우선순위를 가진다. @Autowired @Qualifier("encoder2") private PasswordEncoder passwordEncoder; encoder1 이 @Primary 여도 @Qualifier("encoder2") 가 지정되어 있으면 encoder2 가 선택된다. 정리 같은 타입 Bean 여러 개 ↓ @Primary → 기본으로 사용할 Bean 지정 ↓ @Qualifier → 특정 Bean을 직접 지정 ↓ 둘 다 있으면 @Qualifier가 우선 3. 의존성 주입과 Bean 이름 @Autowired 는 기본적으로 타입(Type)을 기준으로 Bean을 찾는다. 예를 들어: @Autowired private PasswordEncoder passwordEncoder; Spring은 PasswordEncoder 타입의 Bean을 찾는다. 같은 타입의 Bean이 여러 개라면 @Qualifier , @Primary 등을 통해 대상을 결정한다. "타입으로 연결되지 않으면 무조건 Bean 이름으로 찾는다"라고 단순하게 이해하기보다는, 타입 기반 주입에서 후보가 여러 개일 경우 @Primary , @Qualifier 등의 규칙으로 대상을 결정한다 고 이해하는 것이 정확하다. 4. 인증(Authentication)과 인가(Authorization) 웹 애플리케이션의 보안에서 가장 기본적인 개념이다. 인증(Authentication) "당신이 누구인지 확인하는 것" 사용자가 실제로 주장하는 계정의 주인이 맞는지 확인한다. 예: 아이디 + 비밀번호 ↓ 로그인 ↓ 사용자 인증 예를 들어: user@example.com password123 을 입력했을 때 DB의 사용자 정보와 비교하여 해당 사용자가 누구인지 확인한다. 인가(Authorization) "당신이 이 작업을 할 권한이 있는지 확인하는 것" 인증이 끝난 후 특정 리소스에 접근할 권한이 있는지 판단한다. 예: 일반 사용자 → 일반 사용자 페이지 접근 가능 관리자 → 관리자 페이지 접근 가능 또는: GET /users/me → 일반 사용자 가능 DELETE /users/123 → 관리자만 가능 핵심 차이 인증 = 누구인가? 인가 = 무엇을 할 수 있는가? 5. HTTP Request와 Response HTTP는 클라이언트와 서버가 통신하기 위한 프로토콜이다. Request 클라이언트가 서버에 보내는 요청이다. Client ↓ HTTP Request ↓ Server 예: POST /login Content-Type: application/json { "username": "test", "password": "1234" } Response 서버가 클라이언트에게 보내는 응답이다. Client ↑ HTTP Response ↑ Server 예: HTTP/1.1 200 OK { "message": "로그인 성공" } 6. 쿠키(Cookie)와 세션(Session) 쿠키 쿠키는 클라이언트 측에 저장되는 작은 데이터 이다. 서버가 응답할 때 쿠키를 설정할 수 있다. Server ↓ Set-Cookie ↓ Browser 브라우저는 이후 요청에 해당 쿠키를 포함할 수 있다. Browser ↓ Cookie Server 쿠키 자체는 인증 방식이라기보다는 클라이언트에 데이터를 저장하고 HTTP 요청에 함께 전달하기 위한 메커니즘 이다. 세션 세션은 일반적으로 서버 측에서 클라이언트의 상태를 유지하기 위한 방법 이다. 예: 로그인 ↓ 서버에서 세션 생성 ↓ 세션 ID 발급 ↓ 클라이언트의 Cookie에 세션 ID 저장 이후 요청: Client ↓ Cookie: SESSION_ID=abc123 ↓ Server ↓ 세션 저장소에서 abc123 조회 ↓ 사용자 확인 따라서 흔히 사용하는 쿠키 + 세션 인증 구조에서는: Cookie = 클라이언트가 가지고 있는 세션 ID Session = 서버가 관리하는 인증 상태 라고 이해하면 좋다. 7. JWT JWT는 JSON Web Token 의 약자로, JSON 형태의 데이터를 기반으로 사용자 정보를 전달하는 토큰 방식이다. JWT는 크게 세 부분으로 구성된다. Header.Payload.Signature 예: xxxxx.yyyyy.zzzzz JWT의 특징 JWT의 Payload에는 Claim이라는 정보를 저장할 수 있다. 예: { "sub": "123", "username": "test", "role": "USER" } 중요한 점 JWT의 Payload는 암호화되어 있는 것이 아니다. 따라서 JWT를 가지고 있는 사람은 Payload를 디코딩하여 내용을 확인할 수 있다. JWT ↓ Base64URL 디코딩 ↓ Payload 확인 가능 따라서 비밀번호 같은 민감한 정보를 JWT Payload에 넣으면 안 된다. 8. JWT의 Signature JWT의 마지막 부분에는 Signature가 있다. Header.Payload.Signature 서버는 Secret Key 등을 이용하여 Signature를 생성한다. Header + Payload + Secret Key ↓ Signature 클라이언트가 JWT를 서버에 전달하면 서버는 Signature를 검증한다. 이를 통해 JWT가 서버가 발급한 정상적인 토큰인지, 내용이 변조되지 않았는지를 확인할 수 있다. 중요한 점 JWT는 누구나 읽을 수 있지만 임의로 수정해서 정상적인 JWT처럼 사용할 수 있는 것은 아니다. Secret Key가 노출되면 공격자가 정상적인 Signature를 생성할 수 있기 때문에 Secret Key는 반드시 안전하게 관리해야 한다. 9. JWT 인증 흐름 일반적인 JWT 인증 과정: [로그인] Client ↓ 아이디 + 비밀번호 ↓ Server ↓ 사용자 인증 ↓ JWT 발급 ↓ Client 이후 API 요청: Client ↓ Authorization: Bearer JWT ↓ Server ↓ JWT 검증 ↓ 사용자 식별 ↓ API 처리 JWT를 사용할 경우 서버가 매 요청마다 세션 저장소에서 로그인 상태를 조회하지 않아도 JWT 자체의 정보를 검증하여 사용자를 식별할 수 있다. 10. Filter Filter는 웹 애플리케이션에서 HTTP 요청과 응답을 처리하는 중간 단계 에 위치한다. 흐름을 단순화하면: Client ↓ Filter ↓ Controller ↓ Service ↓ Repository ↓ DB 응답은 반대로 돌아간다. DB ↓ Repository ↓ Service ↓ Controller ↓ Filter ↓ Client Filter에서는 요청을 가로채어 필요한 작업을 수행할 수 있다. 예: JWT 검증 인증 처리 요청/응답 로깅 인코딩 처리 공통 보안 처리 Spring Security에서도 Filter를 기반으로 인증 및 보안 처리를 수행한다. 11. Spring Security Spring Security는 Spring 애플리케이션에서 인증(Authentication)과 인가(Authorization), 보안 기능을 제공하는 프레임워크 이다. 대표적으로: 로그인 인증 비밀번호 처리 JWT 인증 권한 검사 URL 접근 제어 CSRF 방어 Security Filter Chain 등의 기능을 제공한다. 핵심 구조 Spring Security에서는 여러 Security Filter가 연결된 형태로 요청을 처리한다. Client Request ↓ Security Filter Chain ↓ 인증 / 권한 검사 ↓ Controller JWT 인증에서도 일반적으로 Filter에서 JWT를 확인하고 인증 객체를 SecurityContext에 등록하는 방식으로 구현한다. 12. Validation 사용자가 입력한 데이터가 올바른 형식인지 검증하는 기능이다. 예: public class SignupRequestDto { @NotBlank private String username; @Email private String email; @Size(min = 8) private String password; } 그리고 Controller에서: @PostMapping("/signup") public ResponseEntity<?> signup( @Valid @RequestBody SignupRequestDto request ) { ... } @Valid @Valid 는 해당 객체에 대해 Bean Validation을 수행하도록 하는 역할 을 한다. @Valid @RequestBody SignupRequestDto request 여기서 DTO에 선언된: @NotBlank @Email @Size @Pattern 등의 조건을 검사한다. 예: email = "hello" ↓ @Email 검사 ↓ 유효하지 않음 ↓ Validation 예외 발생 정리 DTO ↓ @NotBlank @Email @Size @Pattern ↓ @Valid ↓ Bean Validation 실행 13. Entity 연관관계 JPA에서는 Entity 사이의 관계를 표현할 수 있다. 대표적으로: 1 : 1 1 : N N : 1 N : M 이 있다. 13.1 1 : 1 관계 한 Entity가 다른 하나의 Entity와 연결되는 관계이다. 예: User 1 ─── 1 Profile 사용자 한 명당 프로필 하나가 존재한다고 가정할 수 있다. @OneToOne private Profile profile; 단방향 한쪽 Entity만 다른 Entity를 알고 있는 관계이다. User → Profile User에서는 Profile을 조회할 수 있지만 Profile에서는 User를 직접 참조하지 않는다. 양방향 양쪽 Entity가 서로를 참조한다. User ↔ Profile 양방향 관계에서는 연관관계의 주인(owner)을 정해야 한다. 14. 1 : N / N : 1 관계 실무에서 가장 자주 사용하는 관계 중 하나이다. 예: User 1 ───── N Post 사용자 한 명이 여러 개의 게시글을 작성할 수 있다. User ├── Post 1 ├── Post 2 └── Post 3 Entity 관점에서는 보통: // User @OneToMany private List<Post> posts; // Post @ManyToOne private User user; 이런 형태가 된다. 여기서 실제 DB의 외래 키는 일반적으로 N 쪽인 Post 테이블 에 위치한다. post ---------------- id title user_id ← FK 따라서 DB 관점에서는: User 1 ←── N Post 이다. 15. N : M 관계 여러 Entity가 여러 Entity와 연결되는 관계이다. 예: 학생 N ───── M 강의 학생 한 명이 여러 강의를 수강할 수 있고, 강의 하나에도 여러 학생이 수강할 수 있다. 관계형 DB에서는 일반적으로 중간 테이블을 사용한다. Student ↓ StudentCourse ↑ Course 예: student course student_course student_course 가 중간 테이블 역할을 한다. 실무에서는 단순한 @ManyToMany 보다는 중간 Entity를 직접 만들어 관리하는 방식 이 더 유연한 경우가 많다. 예: Student ↓ Enrollment ↓ Course Enrollment에 다음과 같은 추가 정보를 넣을 수도 있다. 수강일 수강상태 점수 16. 영속성 컨텍스트(Persistence Context) JPA를 이해할 때 중요한 개념이다. 영속성 컨텍스트는 쉽게 말하면 JPA가 Entity를 관리하는 공간 이라고 이해할 수 있다. Entity ↓ Persistence Context ↓ DB Entity가 영속성 컨텍스트에서 관리되면 JPA는 Entity의 상태를 추적할 수 있다. 17. Dirty Checking 영속 상태의 Entity가 변경되었을 때 JPA가 변경 내용을 감지하여 DB에 반영하는 기능이다. 예: @Transactional public void updateUsername(Long id, String username) { User user = userRepository.findById(id) .orElseThrow(); user.setUsername(username); } 여기서는 명시적으로: userRepository.save(user); 를 호출하지 않아도 Transaction이 정상적으로 종료될 때 변경 사항이 DB에 반영될 수 있다. 왜냐하면: Entity 조회 ↓ 영속성 컨텍스트에서 관리 ↓ Entity 값 변경 ↓ Dirty Checking ↓ UPDATE SQL 생성 ↓ DB 반영 이 과정이 수행되기 때문이다. 18. @Transactional과 영속성 컨텍스트 @Transactional 은 하나의 작업을 하나의 트랜잭션으로 묶어주는 기능 이다. Spring에서 JPA를 사용할 때 일반적으로 Transaction 범위 안에서 영속성 컨텍스트가 관리된다. 특히 Dirty Checking을 이용한 변경 작업 에서는 Transaction이 중요하다. @Transactional public void updateUser(...) { User user = repository.findById(id) .orElseThrow(); user.setName("변경된 이름"); } Transaction이 시작되면서 Entity가 영속 상태로 관리되고, 메서드가 정상적으로 종료되면 변경 사항을 감지하여 DB에 반영한다. 중요한 구분 @Transactional ↓ Transaction 시작 ↓ 영속성 컨텍스트에서 Entity 관리 ↓ Entity 변경 ↓ Dirty Checking ↓ Transaction Commit ↓ DB 반영 다만 "Transactional이 없으면 영속성 컨텍스트가 무조건 존재하지 않는다" 라고 단순하게 이해하면 안 된다. 조회 자체는 Repository 메서드 내부에서 Transaction이 처리되는 경우도 있기 때문이다. 중요한 것은 Entity를 변경하고 Dirty Checking으로 DB에 반영하려는 작업은 적절한 Transaction 범위가 필요하다 는 것이다. 19. 오늘 내용 핵심 요약 Bean Spring Container가 관리하는 객체 같은 타입 Bean 여러 개 ↓ @Primary → 기본 Bean @Qualifier → 특정 Bean 지정 ↓ Qualifier가 더 우선 인증 / 인가 인증 = 누구인가? 인가 = 무엇을 할 수 있는가? Cookie / Session Cookie → 클라이언트에 저장되는 작은 데이터 Session → 서버 측에서 사용자 상태를 관리 JWT Header.Payload.Signature Payload → 누구나 읽을 수 있음 Signature → Secret Key를 이용해 변조 여부 검증 Secret Key → 절대 외부에 노출하면 안 됨 Filter Client ↓ Filter ↓ Controller 요청/응답을 중간에서 처리할 수 있다. Validation @NotBlank @Email @Size @Pattern ↓ @Valid ↓ Bean Validation JPA Entity ↓ Persistence Context ↓ Dirty Checking ↓ Transaction Commit ↓ DB Entity 관계 1 : 1 1 : N N : 1 N : M 특히 실무에서는 1:N / N:1 관계를 가장 많이 접하게 되고, N:M은 중간 Entity를 두어 풀어내는 경우가 많다. 개념 요약 Bean Bean은 Spring Container가 생성하고 관리하는 객체이며, @Bean 이나 Component Scan 등을 통해 등록할 수 있습니다. @Primary / @Qualifier 같은 타입의 Bean이 여러 개 있을 경우 @Primary 는 기본 Bean을 지정하고, @Qualifier 는 특정 Bean을 명시적으로 선택하며 @Qualifier 가 더 높은 우선순위를 가집니다. 인증 / 인가 인증은 사용자가 누구인지 확인하는 과정이고, 인가는 인증된 사용자가 특정 리소스에 접근할 권한이 있는지 확인하는 과정입니다. JWT JWT는 Header, Payload, Signature로 구성된 토큰이며 Payload는 누구나 읽을 수 있기 때문에 민감한 정보를 저장하면 안 되고, Secret Key를 이용한 Signature 검증으로 토큰의 변조 여부를 확인합니다. Filter Filter는 Controller보다 앞단에서 HTTP 요청과 응답을 가로채 공통 처리를 할 수 있는 기능이며, Spring Security에서는 인증과 인가 같은 보안 처리를 위해 Filter Chain을 사용합니다. @Valid @Valid 는 DTO에 선언된 Bean Validation 조건을 검사하도록 하며 @NotBlank , @Email , @Size 등의 검증 어노테이션과 함께 사용합니다. Dirty Checking JPA에서 영속성 컨텍스트가 관리하는 Entity의 변경 사항을 감지하여 Transaction이 Commit될 때 변경된 내용을 DB에 반영하는 기능입니다. 한 줄 회고 JWT와 Spring Security를 이용한 회원가입 및 로그인 로직을 공부하면서, 사용자 정보를 직접 다루는 만큼 인증·인가 과정과 예외 처리 등 고려해야 할 부분이 많다는 것을 알게 되었다. 단순히 동작하는 코드를 작성하는 것에 그치지 않고, 각 로직이 왜 필요한지와 예외 상황에서 어떻게 동작하는지까지 확실하게 이해하고 넘어가야겠다는 생각이 들었다. 또한 JPA Entity의 관계인 일대일(1:1), 일대다(1:N), 다대일(N:1), 다대다(N:M)의 개념과 기본적인 사용 방법을 이해할 수 있었다. 다만 Entity 간의 관계가 실제 데이터베이스에서 어떤 방식으로 표현되는지,
velog
Should You Buy Google Ads Accounts? Risks and Options Considering purchasing Google Ads accounts to enhance your online presence? Delve into the risks and options associated with this decision. Uncover the potential pitfalls and advantages to make an informed choice that aligns with your digital marketing goals. As we navigate the complex realm of online advertising, this article aims to equip you with valuable insights into the intricacies of buying Google Ads accounts. Stay tuned for expert advice, practical tips, and success stories that will empower you to make strategic decisions for your business growth. If you want to more information just contact now. 24 Hours Reply/Contact ✅Telegram: @smmusareview ✅WhatsApp: +44 7478079809 ✅E-mail: smmusareview24h@gmail.com ✅Website: https://smmusareview.com/product/buy-google-ads-accounts The Importance of Google Ads for Your Business Google Ads, formerly known as Google AdWords, is a powerful online advertising platform that allows businesses to reach potential customers at the exact moment they are searching for products or services related to what the business offers. Using Google Ads effectively can significantly increase your website traffic, lead generation, and sales conversions. By utilizing Google Ads, you can target specific keywords relevant to your business, create compelling ad copy that attracts clicks, and track the performance of your ads in real-time. This data-driven approach not only helps you understand your audience better but also enables you to optimize your ad campaigns for maximum ROI. Embracing Google Ads can give your business a competitive edge in the digital landscape and open up new avenues for growth and success. Understanding the Risks of Buying Google Ads Accounts Before considering purchasing Google Ads accounts, it is crucial to understand the risks involved. One major risk is the potential violation of Google's terms of service, which can result in the suspension or banning of your account. Additionally, bought accounts may have a history of poor performance or misuse, leading to wasted ad spend and a damaged reputation. Furthermore, buying Google Ads accounts can expose you to fraudulent activities and unauthorized access to sensitive information. By not personally managing your ads account from the start, you miss out on valuable insights and control over your campaigns. It's essential to weigh these risks carefully before deciding whether buying Google Ads accounts is worth it for your business. Factors to Consider Before Buying Google Ads Accounts When contemplating the purchase of Google Ads accounts, several crucial factors must be carefully evaluated. First and foremost, assess the legitimacy and reputation of the account seller. Research their track record, reviews, and credibility within the industry to ensure you are dealing with a trustworthy entity. Additionally, consider your own business needs and objectives. Reflect on your advertising budget, target audience, and campaign goals to determine if buying Google Ads accounts aligns with your overall marketing strategy. It's essential to weigh the potential risks against the benefits and evaluate whether purchasing accounts is the right decision for achieving your desired outcomes. Different Options for Buying Google Ads Accounts When considering buying Google Ads accounts, it's crucial to explore the various options available. One option is to purchase established accounts with a history of successful campaigns. These accounts may come at a higher price but can provide immediate access to well-performing ad campaigns and data insights. Another option is to buy aged Google Ads accounts that have been dormant for a while. Reviving these accounts can be cost-effective and potentially offer a fresh start with existing credibility. Additionally, some sellers offer custom-built Google Ads accounts tailored to specific niches or industries, providing a unique advantage in targeting the right audience effectively. Tips for Finding Legitimate Google Ads Accounts Sellers When searching for legitimate Google Ads accounts sellers, it is crucial to conduct thorough research. Look for sellers with a proven track record of providing authentic accounts with positive feedback from previous buyers. Check online forums and reviews to gauge the seller's reputation and reliability. Furthermore, consider reaching out directly to the seller to ask specific questions about their process and the accounts they offer. A trustworthy seller will be transparent about their methods and provide clear information about the accounts' history and performance. By taking these precautions, you can increase your chances of finding a reputable seller and acquiring high-quality Google Ads accounts for your business. How to Safely Purchase Google Ads Accounts When considering purchasing Google Ads accounts, it's crucial to prioritize safety and legitimacy. To ensure a secure transaction, always verify the credibility of the seller. Look for reviews and feedback from previous buyers to gauge their reputation. Additionally, opt for sellers who offer transparent communication and detailed documentation regarding the account's history and performance metrics. Furthermore, consider using reputable third-party platforms or agencies that specialize in facilitating the purchase of Google Ads accounts. These intermediaries can provide an added layer of security by vetting sellers and ensuring that all transactions adhere to industry regulations. By taking these precautions, you can confidently navigate the process of acquiring Google Ads accounts while safeguarding your investment. The Benefits of Buying Google Ads Accounts Investing in purchased Google Ads accounts can offer numerous benefits for businesses looking to enhance their online presence. By acquiring pre-established accounts, you can bypass the initial setup phase and instantly access a wider audience through targeted advertising campaigns. These accounts may already have a history of successful ad campaigns, providing valuable insights and strategies to optimize your own marketing efforts. Moreover, purchasing Google Ads accounts can save you time and resources by leveraging existing account metrics and ad performance data. This can help streamline your marketing activities and improve the overall efficiency of your advertising campaigns. With the right approach and proper management, buying Google Ads accounts can be a strategic investment that yields positive results for your business. Case Studies: Success Stories with Purchased Google Ads Accounts One notable success story involves a small e-commerce business that struggled to gain traction with their Google Ads campaigns. After buying a high-quality Google Ads account from a reputable seller, their click-through rates skyrocketed, leading to a significant increase in sales and revenue. The targeted ads and improved visibility helped them reach a wider audience and convert more customers. In another case, a startup in the tech industry invested in purchasing a Google Ads account to kickstart their online presence. By leveraging the established account's history and credibility, they quickly gained momentum in the competitive market. Their strategic ad placements and optimized keywords resulted in a surge of website traffic and generated valuable leads, setting them on the path to sustainable growth. Alternatives to Buying Google Ads Accounts While purchasing Google Ads accounts may seem like a quick fix for boosting your online presence, it's important to explore alternative strategies that can yield sustainable results. One effective alternative is to invest in comprehensive digital marketing training for your team. By empowering your staff with the knowledge and skills to manage Google Ads campaigns in-house, you can maintain full control over your advertising efforts and ensure long-term success. Another alternative worth considering is hiring a reputable digital marketing agency to handle your Google Ads campaigns. A skilled agency can provide expert guidance, strategic planning, and ongoing optimization to maximize the effectiveness of your ads. By outsourcing this task to professionals, you can focus on other aspects of your business while trusting in their expertise to deliver exceptional results. Conclusion As we conclude our discussion on the topic of buying Google Ads accounts, it is crucial to remember that while there are risks involved, with careful consideration and due diligence, it is possible to find legitimate options that can benefit your business. By understanding the potential pitfalls and exploring alternative strategies, you can make informed decisions that align with your advertising goals. Remember, in the dynamic world of digital marketing, adaptability and innovation are key factors for success.
velog
급한 문제를 해결하려고 서버 설정을 바꾼 상황을 가정해 보겠습니다. 서비스는 다시 동작합니다. 다음 배포 전에는 코드와 실제 값의 차이를 확인합니다. 이 차이가 변경 검토의 입력입니다. CloudFormation은 AWS Resource, 즉 서버와 저장소 같은 대상을 문서로 정의하고 배포하는 서비스입니다. 정의 문서는 Template이고 함께 관리하는 묶음은 Stack입니다. IaC는 구성을 코드로 관리하는 방식입니다. 앞선 조직 점검 편의 IaC를 변경 미리보기, 교체 영향, 실행 후 검증으로 연결하겠습니다. Drift는 기대한 값과 실제 값의 차이입니다 Drift는 Template과 Parameter에 적힌 기대 상태가 실제 Resource 상태와 달라진 상태입니다. Parameter는 Template에 전달하는 입력값입니다. 예를 들어 Template에 설정한 속성이 true 인데 운영 중 false 로 바뀌었다면 확인할 차이가 생깁니다. Drift Detection은 지원되는 Resource의 기대 값과 실제 값을 비교합니다. 담당자는 변경 항목과 시각, 이유를 확인합니다. 긴급 조치로 바뀐 값은 유지 또는 복구할 상태를 정하고 이유를 기록합니다. 검사 범위에는 조건이 있습니다. Template이나 Parameter에 명시한 속성이 비교 대상입니다. 기본값에 맡긴 속성은 추적할 값을 명시했는지 확인합니다. 지원되지 않는 Resource는 NOT_CHECKED 로 표시됩니다. IN_SYNC 는 검사한 지원 대상이 기대 상태와 맞는다는 뜻입니다. 지원 대상이 없는 Stack도 이 상태가 될 수 있으므로 검사한 항목을 함께 봅니다. CloudFormation Drift Detection 문서 에서 상태와 범위를 확인할 수 있습니다. Nested Stack과 확인할 속성을 적습니다 Nested Stack은 다른 Stack 안에 연결된 하위 Stack입니다. 상위 Stack의 Drift 검사에서 하위 Stack의 내부까지 자동으로 검사하는 범위는 제외됩니다. 하위 Stack을 직접 검사하고 결과를 연결합니다. 지원되는 속성과 별도로 확인할 항목도 목록에 남깁니다. 현재 식별값도 기록합니다. 같은 이름으로 다시 만든 Resource를 구분하기 위해서입니다. 검사 후 추가 변경이 생기면 자료를 갱신합니다. 이 글의 연습안은 검사 결과, 변경 이유, 담당자, 하위 Stack을 함께 관리합니다. Change Set 생성과 실행을 연결합니다 Change Set은 제안한 변경으로 어떤 Resource가 추가, 수정, 삭제될지 보여 주는 미리보기입니다. 수정한 Template이나 입력값을 제출해 생성하고 내용을 검토합니다. 생성 단계에서는 제안한 변경으로 Stack의 Resource를 갱신하는 작업이 진행되지 않습니다. 실행 단계에서 해당 변경이 적용됩니다. 검토에는 Resource 이름, 변경할 속성, 교체 가능성, 연결된 서비스, 복구 방법을 붙입니다. 성공적인 미리보기 생성 뒤에도 실행 중 실패가 생길 수 있습니다. 예를 들어 사용자 정의 Resource의 실행 동작은 별도 조건을 가질 수 있습니다. 생성 시 검사와 실행 결과를 각각 확인합니다. Change Set 공식 문서 가 이 순서와 한계를 설명합니다. 승인 기록에는 Change Set ID, 생성 시각, 검토 범위와 담당자를 적습니다. 검토 후 실제 값이 바뀌면 영향을 다시 확인합니다. 현재 상태를 반영하는 미리보기도 확인합니다 현재 문서에는 Drift-aware Change Set이 있습니다. 이 방식은 실제 상태, 이전 배포의 정의, 새 정의를 함께 비교합니다. 긴급 조치로 바꾼 값이 다음 배포에서 어떻게 처리될지 확인하는 데 도움이 됩니다. 검사한 값을 새 정의에 반영하는 선택도 검토할 수 있습니다. 지원 범위를 함께 확인해야 합니다. 지원되지 않는 Resource 유형과 Write-only 속성은 이전 배포 값을 활용하는 비교 범위가 있습니다. Write-only는 입력은 받으며 실제 값을 조회해 반환하는 범위가 제한된 속성입니다. AWS가 관리하도록 설정한 속성은 새 Template에서 바꾸지 않은 경우 실제 값을 유지하는 동작도 있습니다. 변하지 않는 속성의 Drift 조정에는 제한이 있습니다. Drift-aware Change Set 문서 의 지원 유형과 속성 조건을 확인합니다. Replacement에는 데이터와 연결 영향이 붙습니다 Replacement는 기존 Resource를 새 Resource로 교체하는 갱신 방식입니다. 새 Resource에는 새 Physical ID, 즉 실제 대상 식별값이 생깁니다. 일반적으로 새 대상을 만들고 의존하는 Resource의 참조를 연결한 뒤 기존 대상을 정리합니다. 속성마다 갱신 방식이 정해져 있으므로 변경할 속성의 공식 정의도 확인합니다. Resource Update Behavior 문서 가 갱신 방식을 설명합니다. 데이터가 들어 있는 대상은 보존할 자료와 새 대상의 동작까지 계획합니다. UpdateReplacePolicy 는 교체되는 이전 Resource를 삭제, 보존하거나 지원 유형에서 Snapshot을 만드는 방식을 정합니다. Snapshot은 특정 시점의 데이터를 복원할 수 있게 만든 자료입니다. 보존한 대상과 Snapshot에는 비용이 이어질 수 있습니다. UpdateReplacePolicy 문서 에서 지원 조건을 확인합니다. 보존 설정과 데이터 이동은 각각 확인합니다. 복구 자료의 시점, 복원 시험, 새 대상의 읽기와 쓰기, 연결 주소를 계획에 적습니다. 실패 시 되돌릴 구성과 데이터도 확인합니다. 그림은 현재 상태, 미리보기, 교체 영향, 실행 승인, 실제 검증을 연결합니다. 마지막에는 변경 결과와 서비스 요청을 확인합니다. 변경 검토를 위한 개념 그림입니다. JavaScript는 프로그램의 동작을 적는 언어이고 Node.js는 이 코드를 실행하는 도구입니다. 작은 Node.js 예제로 검토 기록을 확인합니다 아래 코드는 이 글의 연습 계획을 검사합니다. driftAt 은 현재 상태 확인 시각, previewAt 은 미리보기 생성 시각입니다. 담당자와 증거 ID가 있으며 확인 순서가 맞는지 계산합니다. 교체가 예정되면 복구 자료 검토 기록도 요구합니다. 필드 이름은 설명용 연습 양식입니다. change-review.mjs 로 저장하고 node change-review.mjs 로 실행할 수 있습니다. 예제는 합성 객체를 읽어 결과를 출력합니다. function review(plan) { const drift = Date.parse(plan.driftAt); const preview = Date.parse(plan.previewAt); const ready = typeof plan.owner === "string" && plan.owner.trim().length > 0 && typeof plan.evidenceId === "string" && plan.evidenceId.length > 0 && plan.nestedReviewed === true && typeof plan.replacement === "boolean" && Number.isFinite(drift) && Number.isFinite(preview) && drift <= preview && (!plan.replacement || plan.recoveryReviewed === true); return ready ? "READY_FOR_REVIEW" : "HOLD"; } const base = { owner: "operator-demo", evidenceId: "evidence-demo", nestedReviewed: true, replacement: true, recoveryReviewed: true, driftAt: "2026-10-06T09:00:00Z", previewAt: "2026-10-06T09:05:00Z", }; console.log(review(base)); console.log(review({ ...base, evidenceId: "" })); console.log(review({ ...base, previewAt: "2026-10-06T08:55:00Z" })); console.log(review({ ...base, owner: "" })); console.log(review({ ...base, recoveryReviewed: false })); READY_FOR_REVIEW HOLD HOLD HOLD HOLD Node.js v24.13.1에서 실행해 위 출력을 확인했습니다. 누락된 증거·담당자·복구 검토와 시각 역전은 HOLD 입니다. READY_FOR_REVIEW 는 사람의 검토에 넘길 조건입니다. 이번 실행은 합성 검토 기록 검사입니다. 실제 Drift 검사, Change Set 생성·실행과 AWS 요청은 수행하지 않았습니다. 실행 후에는 같은 동작을 확인합니다 담당자는 승인한 대상과 변경을 확인하고 운영 절차를 따릅니다. 완료 후 실제 속성, 연결된 서비스, 대표 요청을 확인합니다. 합성 주문 서비스에서는 새 주문 저장과 기존 주문 조회를 검사합니다. 완료 상태, 데이터 복원과 요청 성공을 기록합니다. 제한할 요청도 확인해 Hardening, 즉 보안 설정 보강의 목적을 검토합니다. 차이는 담당자에게 연결하고 다음 정의를 갱신합니다. 확인 문제와 해설 상위 Stack의 Drift 검사를 마쳤다면 Nested Stack은 어떻게 확인할까요? Change Set을 생성한 직후 어떤 단계가 이어지나요? 같은 변경에 Replacement가 추가되면 검토 양식에 무엇을 보충할까요? 해설 하위 Stack을 직접 검사하고 지원 대상과 결과를 연결합니다. 상위 검사의 확인 범위를 분명히 적습니다. 변경할 Resource와 속성, 교체와 서비스 영향을 검토합니다. 승인된 제안을 실행하고 실제 결과를 확인합니다. 복구 자료와 보존 조건, 복원 시험, 새 대상의 데이터와 연결 확인을 추가합니다. 예제는 recoveryReviewed 항목을 확인합니다. 복습과 다음 연결 오늘은 “현재 상태 → 미리보기 → 교체 영향 → 승인 → 검증”을 설명해 보세요. 하루 뒤에는 Nested Stack이 추가된 합성 양식에 확인 범위를 적습니다. 7일 뒤에는 긴급 조치의 설정을 다음 배포에 연결해 봅니다. 복습 제안 일정입니다. 공식 문서 확인일은 2026-10-06입니다. 다음 글 [AWS Hardening 14] Incident Drill에서 조사와 복구를 연습하기 에서는 증거, 승인된 격리, 접근 경로, 서비스 복구를 한 사건 기록으로 연결하겠습니다.
velog
1. 3 Layer Architecture 기존 메모장 프로젝트에서는 하나의 Controller에서 API 요청부터 DB 작업까지 모두 처리하고 있었다. 기능이 많아질수록 한 클래스에 코드가 몰리게 되고, 수정이나 유지보수가 어려워진다. 이를 해결하기 위해 역할을 Controller → Service → Repository 로 분리한다. Controller 클라이언트의 요청을 받는 역할 HTTP 요청 처리 Request 데이터 전달 Service 호출 처리 결과를 Client에게 응답 Service 비즈니스 로직 을 담당 사용자의 요구사항 처리 비즈니스 로직 수행 DB 작업이 필요하면 Repository에 요청 Repository DB와 직접적으로 통신하는 역할 DB 연결 및 관리 CRUD 작업 SQL 실행 전체 흐름 Client ↓ Controller ↓ Service ↓ Repository ↓ Database 각 계층의 역할을 분리하면 코드의 가독성, 유지보수성, 확장성 을 높일 수 있다. 2. IoC와 DI 의존성 한 객체가 다른 객체를 필요로 하는 관계를 의미한다. 예를 들어 Consumer 가 Chicken 을 직접 생성해서 사용한다면 두 객체가 강하게 결합되어 있다. public class Consumer { void eat() { Chicken chicken = new Chicken(); chicken.eat(); } } 이 상태에서는 Chicken 을 Pizza 로 변경하려면 Consumer 의 코드까지 수정 필요 약한 결합 인터페이스를 사용하면 객체 간 결합도를 낮출 수 있다. interface Food { void eat(); } Consumer 는 Chicken 이나 Pizza 자체가 아니라 Food 에 의존한다. Consumer → Food ↑ Chicken / Pizza 따라서 실제 구현체가 변경되어도 Consumer 의 코드를 크게 수정하지 않아도 된다. DI (Dependency Injection) 필요한 객체를 외부에서 주입받는 것 객체가 필요한 의존성을 직접 생성하지 않고 외부에서 전달받는다. 대표적인 방법은 생성자 주입 이다. public class Consumer { private final Food food; public Consumer(Food food) { this.food = food; } } 생성자 주입의 장점 객체 간 결합도 감소 의존성 관리 용이 테스트 용이 객체의 불변성 확보 Spring에서는 일반적으로 생성자 주입을 권장 한다. IoC (Inversion of Control) 제어의 역전 객체의 생성과 의존성 관리에 대한 제어권을 개발자가 직접 갖는 것이 아니라 Spring이 관리하는 구조 이다. 기존에는 Controller → Service 생성 Service → Repository 생성 과 같이 객체를 직접 생성했다. DI를 적용하면 Repository → Service → Controller 형태로 필요한 객체를 외부에서 주입받는다. 즉, 객체의 생성과 의존성 관리에 대한 제어가 역전된다. 3. IoC Container와 Bean Bean Spring이 생성하고 관리하는 객체 Spring은 애플리케이션 실행 시 필요한 객체를 생성하고 IoC Container에서 관리한다. IoC Container Spring Bean을 생성하고 관리하는 컨테이너 Spring IoC Container ├─ Controller Bean ├─ Service Bean └─ Repository Bean @Component 클래스를 Spring Bean으로 등록할 때 사용한다. @Component public class MemoService { } @ComponentScan @Component 가 붙은 클래스를 찾아 Bean으로 등록한다. @SpringBootApplication 에 기본적으로 설정되어 있다. 4. Spring의 3 Layer Annotation Spring에서는 각 계층의 역할을 나타내는 애너테이션을 제공한다. Annotation 역할 @Controller Controller 역할 @RestController REST API Controller @Service Service 역할 @Repository Repository 역할 이 애너테이션들은 모두 @Component 를 포함하고 있기 때문에 Spring Bean으로 등록된다. 5. JPA란? ORM Object-Relational Mapping 객체와 관계형 데이터베이스의 데이터를 매핑하는 기술이다. 기존에는 DB 작업을 위해 직접 SQL을 작성하고 JDBC를 사용해야 했다. Java 객체 ↓ SQL 작성 ↓ JDBC 실행 ↓ Database 데이터 구조가 변경되면 SQL과 객체 변환 코드도 함께 수정해야 하는 문제가 있다. JPA Java Persistence API Java ORM 기술에 대한 표준 명세 JPA를 사용하면 객체를 중심으로 DB 데이터를 다룰 수 있다. Java 객체 ↓ JPA ↓ Database 개발자가 직접 SQL을 작성하는 작업을 줄이고 객체 중심으로 DB를 관리할 수 있다. Hibernate JPA의 구현체 중 하나 Spring Boot에서는 기본적으로 Hibernate를 사용한다. JPA = 표준 명세 Hibernate = JPA 구현체 6. Entity JPA가 관리하는 객체 Entity 클래스는 DB 테이블과 매핑된다. @Entity @Table(name = "memo") public class Memo { @Id private Long id; @Column(nullable = false) private String username; @Column(nullable = false, length = 500) private String contents; } 주요 Annotation Annotation 역할 @Entity JPA가 관리하는 Entity로 지정 @Table 매핑할 테이블 지정 @Column 필드와 컬럼 매핑 @Id 기본 키 지정 @GeneratedValue 기본 키 자동 생성 @GeneratedValue @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; DB의 AUTO_INCREMENT 와 같이 기본 키 생성을 DB에 위임할 수 있다. 7. 영속성 컨텍스트 Entity 객체를 효율적으로 관리하기 위한 공간 JPA는 Entity를 바로 DB에 저장하는 것이 아니라 영속성 컨텍스트에서 관리 한다. EntityManager 영속성 컨텍스트에 접근하여 Entity를 관리하는 객체 EntityManager ↓ 영속성 컨텍스트 ↓ Entity Entity의 저장, 조회, 수정, 삭제 등을 관리한다. 8. 영속성 컨텍스트의 주요 기능 1차 캐시 영속성 컨텍스트 내부에는 Entity를 저장하는 캐시가 존재한다. 1차 캐시 Key → Value @Id Entity em.find() 를 호출했을 때 먼저 1차 캐시를 확인한다. em.find() ↓ 1차 캐시 확인 ↓ 있음 → 캐시에서 반환 ↓ 없음 → DB 조회 → 1차 캐시 저장 → 반환 1차 캐시의 장점 DB 조회 횟수 감소 같은 Entity에 대한 객체 동일성 보장 쓰기 지연 JPA는 INSERT , UPDATE , DELETE SQL을 바로 DB에 보내지 않고 쓰기 지연 저장소 에 모아둘 수 있다. 트랜잭션이 커밋되거나 flush() 가 호출되면 SQL을 DB에 반영한다. Entity 변경 ↓ 쓰기 지연 저장소 ↓ flush() ↓ DB flush() 영속성 컨텍스트의 변경 내용을 DB에 반영 쓰기 지연 저장소에 있는 SQL을 DB에 전달한다. 단, INSERT , UPDATE , DELETE 와 같은 변경 작업을 DB에 반영하려면 트랜잭션이 필요하다. 변경 감지 (Dirty Checking) JPA에서는 별도의 update() 메서드를 호출하지 않아도 Entity의 변경 내용을 감지하여 UPDATE SQL을 생성한다. Entity 조회 ↓ 최초 상태 저장 ↓ Entity 값 변경 ↓ 트랜잭션 commit ↓ flush() ↓ 최초 상태와 현재 상태 비교 ↓ 변경된 내용이 있다면 UPDATE SQL 생성 따라서 다음과 같이 Entity의 값만 변경해도 된다. Memo memo = em.find(Memo.class, id); memo.setUsername("Update"); memo.setContents("변경된 내용"); 이후 트랜잭션이 커밋되면 변경 사항이 DB에 반영된다. 9. Entity의 상태 JPA에서 Entity는 영속성 컨텍스트와의 관계에 따라 상태가 달라진다. 비영속 (Transient) Memo memo = new Memo(); 아직 영속성 컨텍스트에서 관리하지 않는 상태 영속 (Managed) em.persist(memo); 영속성 컨텍스트가 Entity를 관리하는 상태 준영속 (Detached) em.detach(memo); 영속 상태였던 Entity를 영속성 컨텍스트에서 분리한 상태 준영속 상태에서는 JPA의 변경 감지 등의 기능을 사용할 수 없다. 삭제 (Removed) em.remove(memo); Entity를 삭제 대상으로 지정한 상태 상태 정리 비영속 ↓ persist() 영속 ↓ detach() 준영속 영속 ↓ remove() 삭제 10. 영속성 컨텍스트 관리 메서드 persist() 비영속 Entity를 영속 상태로 만든다. em.persist(memo); find() Entity를 조회한다. em.find(Memo.class, id); detach() 특정 Entity를 영속성 컨텍스트에서 분리한다. em.detach(memo); clear() 영속성 컨텍스트를 초기화한다. em.clear(); 관리하고 있던 모든 Entity가 준영속 상태가 된다. close() 영속성 컨텍스트를 종료한다. em.close(); merge() 준영속 또는 비영속 Entity를 다시 영속 상태로 병합한다. Memo mergedMemo = em.merge(memo); merge() 의 반환값이 새롭게 영속 상태가 된 Entity라는 점이 중요하다. 11. Transaction 여러 DB 작업을 하나의 작업 단위로 묶는 개념 모든 작업이 성공하면 Commit , 하나라도 실패하면 Rollback 한다. Transaction 시작 ↓ DB 작업 ↓ 성공 → COMMIT 실패 → ROLLBACK @Transactional Spring에서는 @Transactional 을 사용하여 트랜잭션을 쉽게 적용할 수 있다. @Transactional public void updateMemo() { // DB 작업 } 정상적으로 실행되면 Commit하고, 예외가 발생하면 Rollback한다. readOnly = true 조회 전용 트랜잭션에서 사용한다. @Transactional(readOnly = true) 조회 작업에 대한 최적화가 가능하다. 12. 영속성 컨텍스트와 Transaction Spring 환경에서는 트랜잭션과 영속성 컨텍스트의 생명주기 가 연결되어 있다. 트랜잭션이 유지되는 동안 영속성 컨텍스트도 유지되기 때문에 JPA의 기능을 사용할 수 있다. 따라서 JPA에서 DB에 데이터를 저장, 수정, 삭제 하려면 트랜잭션 적용이 필요하다. 조회는 단순 조회라면 트랜잭션이 필수는 아니지만, 상황에 따라 트랜잭션이 필요한 경우가 있다. 13. Transaction 전파 Spring에서는 Service에서 Repository까지 트랜잭션을 전달할 수 있도록 트랜잭션 전파 기능을 제공한다. @Transactional 의 기본 전파 옵션은 REQUIRED 이다. REQUIRED 부모 메서드에 트랜잭션이 존재하면 자식 메서드가 부모 트랜잭션에 참여 한다. Service @Transactional ↓ Repository @Transactional → 하나의 Transaction으로 동작 즉, 여러 계층에서 @Transactional 이 사용되더라도 기존 트랜잭션이 있다면 새로운 트랜잭션을 만드는 것이 아니라 기존 트랜잭션에 합류한다. 14. Spring Boot에서 JPA 사용 Spring Boot에서는 JPA 설정을 보다 쉽게 할 수 있다. 의존성 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' application.properties spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true ddl-auto 옵션 역할 create 기존 테이블 삭제 후 생성 create-drop 생성 후 애플리케이션 종료 시 삭제 update 변경된 부분만 반영 validate Entity와 테이블 매핑 검증 none 아무 작업도 하지 않음 개발 환경에서는 설정에 따라 편리하게 사용할 수 있지만, 운영 환경에서는 데이터 손실 가능성을 고려해야 한다. 15. Spring Data JPA JPA를 쉽게 사용할 수 있도록 만들어진 Spring Data의 모듈 JPA를 직접 사용하면 EntityManager 등을 이용해 DB 작업을 처리해야 한다. Spring Data JPA에서는 JpaRepository 를 제공하여 반복적인 CRUD 코드를 줄일 수 있다. public interface MemoRepository extends JpaRepository<Memo, Long> { } Spring Data JPA가 Repository의 구현체를 자동으로 생성하기 때문에 직접 구현 클래스를 작성할 필요가 없다. 16. JpaRepository 주요 메서드 save() Entity 저장 memoRepository.save(memo); findAll() 전체 데이터 조회 memoRepository.findAll(); findById() ID를 기준으로 조회 memoRepository.findById(id); 반환 타입은 Optional 이다. memoRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("메모가 존재하지 않습니다.") ); delete() Entity 삭제 memoRepository.delete(memo); 17. 변경 감지를 이용한 수정 Spring Data JPA에는 별도의 update() 메서드가 없다. Entity를 조회한 후 값을 변경하면 변경 감지(Dirty Checking) 를 통해 UPDATE SQL이 생성된다. @Transactional public Long updateMemo(Long id, MemoRequestDto requestDto) { Memo memo = findMemo(id); memo.update(requestDto); return id; } 여기서 중요한 것은 @Transactional 이다. 트랜잭션이 종료될 때 변경 감지가 수행되고 DB에 UPDATE가 반영된다. 18. JPA Auditing 생성 시간이나 수정 시간을 Entity마다 직접 관리하는 것은 번거롭다. Spring Data JPA에서는 JPA Auditing 을 통해 생성일과 수정일을 자동으로 관리할 수 있다. @CreatedDate Entity가 처음 생성될 때 시간을 자동으로 저장한다. @LastModifiedDate Entity가 수정될 때 수정 시간을 자동으로 변경한다. @MappedSuperclass 공통으로 사용하는 필드를 여러 Entity가 상속받을 수 있도록 한다. @Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class Timestamped { @CreatedDate @Column(updatable = false) private LocalDateTime createdAt; @LastModifiedDate private LocalDateTime modifiedAt; } 그리고 Spring Boot 애플리케이션에 다음 설정을 추가한다. @EnableJpaAuditing Entity에서 상속받아 사용한다. public class Memo extends Timestamped { } 19. Query Methods Spring Data JPA에서는 메서드 이름을 이용하여 SQL을 생성 할 수 있다. 예를 들어 List<Memo> findAllByOrderByModifiedAtDesc(); 위 메서드는 modifiedAt 을 기준으로 내림차순 조회한다. 또한 조건을 메서드 이름에 표현할 수 있다. List<Memo> findAllByContentsContainsOrderByModifiedAtDesc( String keyword ); → contents 에 특정 keyword 가 포함된 데이터를 조회하고 수정일 기준으로 내림차순 정렬 Query Methods의 장점 SQL 직접 작성 감소 Repository 구현 코드 감소 메서드 이름만으로 조회 조건 표현 가능 20. 이번 주 핵심 정리 이번 주에 배운 내용을 흐름으로 정리하면 다음과 같다. 3 Layer Architecture ↓ Controller / Service / Repository 역할 분리 ↓ IoC / DI ↓ Spring IoC Container ↓ Bean 관리 ↓ JPA ↓ Entity ↓ 영속성 컨텍스트 ↓ 1차 캐시 / 쓰기 지연 / 변경 감지 ↓ Transaction ↓ Spring Data JPA ↓ JpaRepository ↓ Query Methods 꼭 기억할 키워드 3 Layer Architecture Controller Service Repository IoC 제어의 역전 DI 의존성 주입 생성자 주입 권장 Bean Spring이 관리하는 객체 JPA Java ORM 표준 명세 Hibernate JPA 구현체 Entity JPA가 관리하는 객체 영속성 컨텍스트 Entity를 관리하는 공간 1차 캐시 Entity 조회 성능 및 객체 동일성 보장 Dirty Checking Entity 변경 감지 → UPDATE SQL 생성 flush 영속성 컨텍스트의 변경 내용을 DB에 반영 Transaction Commit / Rollback @Transactional Spring에서 트랜잭션 적용 Transaction Propagation REQUIRED 가 기본값 기존 트랜잭션에 참여 Spring Data JPA JPA 사용을 편리하게 해주는 모듈 JpaRepository 기본 CRUD 기능 제공 JPA Auditing 생성일 / 수정일 자동 관리 Query Methods 메서드 이름으로 조회 조건 생성 마무리 이번 주에는 단순히 JPA 사용법만 배운 것이 아니라 Spring이 객체와 DB를 어떻게 관리하는지 를 중심으로 학습했다. 특히 IoC → DI → Bean → JPA → 영속성 컨텍스트 → Transaction → Spring Data JPA 가 서로 연결되어 있다는 점을 이해하는 것이 중요했다. 기존에는 Repository에서 직접 SQL을 작성했다면, Spring Data JPA를 사용하면서는 JpaRepository 와 Query Methods를 통해 훨씬 적은 코드로 DB 작업을 처리할 수 있다. 다음에는 이번에 배운 내용을 실제 프로젝트에 적용하면서 Entity 설계와 Repository, Service 계층을 직접 구성해보는 것 이 중요할 것 같다.
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%
Score: 54.4Confidence: 49%