관리자로 접근
mysql -u root -p
모든 데이터베이스 확인
show databases;
데이터베이스 지정
use 이름 ;
한꺼번에 지정
mysql -u root -p 이름
'개발자로 업그레이드 되자 > MySQL' 카테고리의 다른 글
자동증가 (0) | 2022.03.07 |
---|---|
자료형 (0) | 2022.03.07 |
관리자로 접근
mysql -u root -p
모든 데이터베이스 확인
show databases;
데이터베이스 지정
use 이름 ;
한꺼번에 지정
mysql -u root -p 이름
자동증가 (0) | 2022.03.07 |
---|---|
자료형 (0) | 2022.03.07 |
Vue 컴포넌트
복잡한 화면을 조합하여 구성하도록 재사용 가능한 Vue인스턴스이다
지역/ 전역으로 구분된다
컴포넌트를 등록하면 동시에 상위 컴포넌트가 된다
1. 전역 컴포넌트
Vue.component(' 이름 ' , {
});
2. 지역 컴포넌트
new Vue({
components: {
' 이름 ' : 내용
}
})
컴포넌트 명명 규칙 :
1) 케밥케이스 : 소문자 + -
HTML 템플릿에서 그대로 이름을 사용한다
2) 파스칼케이스: 맨앞단어 대문자
HTML 템플릿에서 1) 2) 두가지 모두 사용가능하다
컴포넌트 통신:
Vue 컴포넌트는 기본적으로 데이터 주고받기 불가능 -> props를 이용하여 가능하다
props는 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 사용하는 속성이다
v-bind를 통해 넘겨준다
만들며 공부하는 Vue.js + SpringBoot + JPA(1) (0) | 2022.02.25 |
---|---|
1. Vue CLI 설치 (0) | 2021.12.31 |
학원 수업도 끝났고 남는 시간에 한 번 만들어봐야겠다 생각만 하던 조합으로
프로젝트를 만들어 봐야겠다
[실전 SPA 개발 Vue.js with 타입스크립트 + 스프링 부트]
--전자책이라 엄청 신경써서 만드신건지 페이지분량이 어마무시하다..
+ 인프런 김영한 강사님의 스프링 / JPA강의를 참고하며 진행한다.
1. Vue 생성
Vue() 생성자를 사용해 생성된 객체를 Vue 인스턴스라고 한다. DOM 요소에 마운트 해 Vue 기능을 사용한다
<div id="app">
{{message}}
</div>
new Vue({
el : '#app', //요소
data: {
message: 'Hello Vue!'
}, //데이터
computed: {
//computed 는 data 속성의 데이터에서 파생된 값을 공개하여 data 속성과 마찬가지로
//템플릿에서 사용할 수 있게 한다. 함수형태지만 ()를 붙히지 않고 data값처럼 사용한다
},
methods : {
//methods 는 이벤트 처리 콜백함수 정의나 데이터 가공 함수 정의로 사용한다
//computed는 캐시기능을 지원하고 methods는 매번 호출시 새로 실행을 보장한다
},
watch :{
//watch는 데이터 변화를 감지하여 자동으로 특정 로직을 수행한다.
//비동기 처리에 적합하다
},
filters: {
//필터는 | 왼쪽 하나의 인자를 받아 함수 형태로 정의한다
//ex totalprice | numberFormat 으로 totalprice를 받아 화폐단위로 변환 등
}
)}
//el없이
new Vue({
data: {
message: 'Hello Vue!'
}
)}.$mount('#app');
2. Vue의 인스턴스 라이프 사이클(생성부터 소멸까지)
beforeCreate -> data 속성과 methods 속성이 아직 인스턴스에 정의되어 있지 않다
created -> data와 methods 접근 가능
beforeMount -> el 속성에 지전항 화면 요소에 인스턴스 부착 전 호출 단계
mounted -> 인스턴스 부착 후 호출 단계
beforeUpdate -> 관찰하고 있는 데이터가 변경되면 가상 DOM으로 화면을 다시 그리기 전에 호출되는 단계
updated -> 데이터가 변경되고 나서 가상 DOM으로 다시 화면을 그리고나면 실행되는 단계
beforeDestroy -> 인스턴스 접근은 가능하므로 삭제하기 좋은 단계
destroyed -> 모든 속성 제거 후 인스턴스 파괴
3. Vue 템플릿 문법
템플릿은 Vue 인스턴스의 데이터와 뷰의 관계를 선언적으로 정의하는 역할
템플릿 문법으로 Mustache ( {{ }} ) / v-bind ( : ) 존재
4. 디렉티브 = Vue.js의 독자 정의 속성
v-if | 지정한 뷰 데이터 값의 참 거짓 여부에 따라 HTML을 표시한다 |
v-for | 뷰 데이터 개수만큼 HTML 반복 출력 |
v-show | 데이터 진위 여부에 따라 display:none으로 만든다 |
v-bind | HTML 태그의 기본 속성과 뷰 데이터 속성을 연결한다 |
v-on | 화면 요소의 이벤트를 감지하여 처리할 때 사용한다 |
v-model | 폼에 입력한 값을 뷰 인스턴스의 데이터와 즉시 동시화한다 (input, select , textaea 에 사용) |
<tr>
<td>비밀번호</td>
<td><input type="password" v-bind:value="userPw"/></td>
</tr>
<tr>
<td>소개</td>
<td><textarea rows="5" v-bind:value="introduction"></textarea></td>
</tr>
<tr>
<td>개발자여부</td>
<td><span v-if="developer">개발자</span></td>
<td><span v-else>개발자아님</span></td>
</tr>
<tr>
<td>외국인여부</td>
<td><span v-show="foreigner==='yes'">외국인</span></td>
</tr>
<tr>
<td>사용자아이디</td>
<td>
<input type="text" v-on:input="userId=$event.target.value" v-bind:value="userId">
//+ ex) v-on:change="~"
</td>
</tr>
new Vue({
el : "#app",
data : {
userId: "alex",
userPw: "1234",
introduction: "hello",
developer : false,
foreigner : "no",
hobbyList : ["Sports" , "Music" , "Movie"],
gender:"male",
nationality : "01"
},
computed : {
getNationality: function(){
if(this.nationality ==="01"){
return "Korea";
}else if(this.nationality ==="02"){
return "Germany";
}else{
return "None";
}
}
},
methods :{
//데이터 값
onSubmit(){
const{ .....변수명} = this
}
}
})
만들며 공부하는 Vue.js + SpringBoot + JPA(2) (0) | 2022.02.25 |
---|---|
1. Vue CLI 설치 (0) | 2021.12.31 |
자바스크립트 방식 Ajax에 무한스크롤을 구현해본다
let lastpage = false; //마지막 페이지 설정
let oneTime = false; //한번만 실행을 보장하는 변수
let first = true; //맨처음 접속시 실행됨을 보장하는 변수
classScroll();
function classScroll(){
const screenHeight = screen.height;/* 화면크기 */
if(first&& !oneTime){
oneTime = true;
first =false;
addClassLine();//컨텐츠 추가 발동
}//맨처음 실행
document.addEventListener('scroll',OnScroll,{passive:true}) // 스크롤 이벤트함수정의
function OnScroll () { //스크롤 이벤트 함수
const fullHeight = infinitebox.clientHeight; // infinite 클래스의 높이 , 스크롤 이벤트 안에서 정의해야 추가된 높이가 다시 계산된다
const scrollPosition = scrollY; // 스크롤 위치
if (fullHeight-screenHeight*1/4 <= scrollPosition && !oneTime && !lastpage && !first) {
oneTime = true; // oneTime 변수를 true로 변경해주고,
addClassLine();//컨텐츠 추가 발동
}
}
}
function addClassLine(){
//ajax를 통한 데이터 추가
}//컨텐츠 추가 발동
Ajax - 자바스크립트 방식 (0) | 2022.02.02 |
---|---|
JSON / GSON (0) | 2021.12.08 |
Ajax개념 및 기초 사용법 (0) | 2021.12.08 |
1. XMLHttpRequest 객체 생성
2. 설정 및 데이터 세팅
3. readyState가 변화했을 때 응답을 받고 데이터 처리
//통신에 사용될 XMLHttpRequest 객체 정의
let httpRequest = new XMLHttpRequest();
const 보낼 데이터 = {}
/* Post 방식으로 요청 */
httpRequest.open("POST", 요청할URL입력 , true);
/* Response Type 을 Json으로 */
httpRequest.responseType = "json";
/* 요청 헤더에 컨텐츠 타입 json 명시 */
httpRequest.setRequestHeader("Content-Type", "application/json");
/* 데이더 json으로 변환 후 전송하기 */
httpRequest.send(JSON.stringify(reqJson));
//readyState가 변화했을 때 함수 실행
httpRequest.onreadystatechange = ()=>{
if(httpRequest.readyState === XMLHttpRequest.DONE){
//readyState가 Done이고 응답값이 200이면
if(httpRequest.status ===200){
//성공
}
else{
//실패
}
}
}
Ajax로 구현하는 무한스크롤 (0) | 2022.02.02 |
---|---|
JSON / GSON (0) | 2021.12.08 |
Ajax개념 및 기초 사용법 (0) | 2021.12.08 |
Ex) 로그인 시 아이디 정보를 저장 checkbox 표현 시
1. 세션에 저장된 login정보 가져오기
(Spring 에서 세션으로 저장하기 : @SessionAttributes + Model 객체 방식으로도 가능하다)
받아올 때 @ModelAttribute 객체로 받아오고 + 클래스에 @SessionAttributes({객체명}) 선언으로
model 객체를 session으로 사용한다.
2. 쿠키 생성
Cookie cookie = new Cookie("saveId" , 객체.getId() );
3. 쿠키 유효기간 설정 + 사용될 경로 설정
if(아이디저장 체크박스 value !=null) {
//아이디 저장 체크 시
cookie.setMaxAge(60*60*24*30);
}
else {
cookie.setMaxAge(0);
//체크 해제 시 유효기간 = 0
// 가지고 있던 쿠키가 사라진다
}
cookie.setPath(req.getContextPath());
(HttpServletRequest 객체로 루트를 가져온다
(HttpServletResponse 객체로 전송한다)
resp.addCookie(cookie);
Spring - AOP (0) | 2022.01.19 |
---|---|
Spring 스케줄러 (0) | 2022.01.14 |
SPRING MVC에서 Mybatis 활용 (0) | 2022.01.13 |
스프링 MVC - 이미지 업로드 / 파라미터 사용 DB삽입 (0) | 2022.01.11 |
스프링MVC - 트랜잭션 및 예외처리 (0) | 2022.01.06 |
[ DNS ]
IP는 기억이 어렵고 추후 변경이 가능하다
이를 해결하기 위한 것이 DNS == IP주소를 이름으로 바꾸는 개념
[ URI와 웹 브라우저 요청의 흐름 ]
1. URI : Uniform Resource Identifier
- URI는 로케이터 ,이름 또는 둘 다로 추가 분류될 수 있다
(로케이터 : 리소스가 있는 위치를 지정 , 이름 : 리소스의 이름- 위치는 변하지만 이름은 변하지 않는 장점 )
- 결국 URI는 URL(로케이터) + URN(네임) 을 포괄한는 개념
-하지만 URN 이름만으로 실제 리소스를 찾을 수 있는 방법이 보편화 되지 않음
-결국 흔히 사용하는것은 URL의 개념
-URL : scheme://[userinfo@]host[:port][/path][?query][#fragment] 의 작성법을 가짐
[ 웹브라우저의 요청흐름 ]
1. 클라이언트 : DNS를 조회 + HTTPS PORT 생략 + HTTP 요청메시지 생성
2. 생성되면 TCP 등을 추가하고 확인 후 서버로 전송
3. 서버가 받으면 똑같이 응답
[ HTTP ] - Hyper Text Transfer Protocol == 인터넷에서 정보를 주고받는 규칙
1. HTTP 메시지에 모든 것을 전송한다 ( 텍스트, 이미지, JSON, 영상...)
2. 1.1 버전을 기본으로 2, 3 발전 중 ( 1.1 ,2 : TCP / 3 : UDP 주로 사용 )
--현재는 1.1을 주로 사용하는 상태임
3. 클라이언트 서버 구조
4. 무상태 프로토콜 지향
무상태 프로토콜? (stateless)
1. 서버가 이전 상태를 유지하지 않는다 == 요청을 받으면 보관하지 않고 응답만 계속 보냄
2. 서버가 바뀌어도 그대로 진행됨 == 무제한 서버 증설 가능
3. 한계가 존재하는 경우 생김 ( ex 로그인 정보 유지 )
4. 정보를 매번 다 보내야하므로 정보가 커짐
(vs 상태유지 == 요청을 받으면 보관하고 응답 == 서버가 바뀌면 유지 정보를 다시 전달해주지 못할 수 있어 오류)
--일반적으로 브라우저 쿠키와 서버 세션등을 사용해서 상태 유지
--상태 유지는 최소한만 사용하는 것이 좋다
[비연결성]
1. 연결을 유지하는 모델 : TCP / IP
2. 연결을 유지하지 않는 모델 : HTTP
-- 처리 요청이 적으면 매우 효율적이나 페이지 넘어가면 매번 TCP 연결 절차로css, js등 매번 다운로드 발생
-- 지금은 HTTP 지속 연결(Persistent Connections)로 문제 해결
HTTP 개념 1 (0) | 2022.01.25 |
---|
인터넷 통신은 클라이언트 -> 서버로 갈때 수많은 노드를 지나가서 도착한다
[ 순서 ]
1. IP주소 부여 ( = 인터넷 프로토콜 )
2. 패킷 단위로 보내게됨( 내 IP , 도착 IP , 메세지 정보등을 가짐) -> 노드를 거쳐 도착 IP로
3. 서버가 받아서 반대로 응답
--> 한계가 발생
1. 비연결성 ( 패킷을 받을 대상이 없거나 불능이여도 보내고 봄 )
2. 비신뢰성 ( 패킷이 사라지거나 나눠보냈는데 순서대로 도착하지 않을 수 있음)
3. 프로그램 구별 문제 ( 같은 IP에서 통신하는 어플이 둘 이상인 경우 구분하기가 어려움 )
--> 이를 해결하기 위해 TCP/ UDP 개념이 쓰임
[ 인터넷 프로토콜 스택의 4계층 ]
1. 애플리케이션 계층 - HTTP, FTP
2. 전송 계층 - TCP, UDP
3. 인터넷 계층 - IP
4. 네트워크 인터페이스 계층 (LAN 장비)
==> 메세지 생성 -> TCP 정보 추가 -> IP 패킷 추가 -> LAN 카드에서 전송 으로 진행됨
TCP? 전송 제어 프로토콜 / 전송 제어, 순서 , 검증 정보를 포함하고 있음 -> 기존 한계점 해결
-특징-
(1) 연결지향 (가상 연결로 연결가능 확인 후 보냄 )
(2) 데이터 전달 보증 (정상 도착을 확인)
(3) 순서 보장
(4) PORT가 포함되어 있어 구별가능
UDP? 사용자 데이터그램 프로토콜 / IP와 유사하지만 PORT + 체크섬 추가
-특징-
(1) 단순하고 빠름
(2) 특별한 기능은 없지만 TCP가 정확함에도 속도 최적화가 어려워 이를 보완하기 위해 쓰임
(3) 애플리케이션에서 추가 작업 가능
HTTP 개념 2 (0) | 2022.01.25 |
---|
Java Persistence API - 자바 ORM 기술 표준
[ ORM이란] Object-relational-mapping : 객체 관계 매핑
객체와 RDBMS의 중간에서 매핑해주는 기술
WHY JPA?
객체와 RDMBS의 괴리로 객체답게 모델링할수록 의미없는 매핑 작업만 늘어나게된다.
객체를 자바의 형태로 DB에 저장할 수 있도록 도움 필요
--> SQL 중심적인 개발에서 객체 중심의 개발이 가능해진다
==생산성 증가, 유지보수 유리 / 객체-> SQL의 패러다임 불일치 해결
==데이터 접근 추상화
JPA의 구동 방식
1. (설정정보 조회)-> Persistence ->
2. EntityManagerFactory 생성 (하나만 생성되어 앱 전체에서 공유됨) ->
3. EntotyManager 생성 (쓰레드간 공유하면 안된다)
--> JPA의 모든 데이터변경은 트랜잭션 안에서 실행된다
-매핑-
1. 객체와 테이블 매핑
@Entity : JPA가 관리할 객체 (클래스)
@Id : DB PK와 매핑되는 필드
-JPQL-
SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어
JPA를 통한 객체 중심 개발에서 문제가 되는 검색 쿼리의 문제 해결에 이용
검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 하게 해준다
이 과정에서 결국 조건이 포함된 SQL이 불가결대상이 되긴한다
SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
엔티티 설계시 주의점 (0) | 2022.09.27 |
---|---|
영속성 (0) | 2022.09.06 |
AOP란? -> 관점 지향 프로그래밍의 약자
=공통되는 부분을 따로 빼내어 필요한 시점에 해당코드를 추가해주는 기술
ex)컨트롤러 -> 서비스 이동시마다 println 을 실행한다면?
1. Advice : 공통되는 부분을 따로 빼내어 작성하는 메소드
2. JoinPoint : Advice가 적용될 수 있는 모든 관점(시점) -> 매우많음
3. Pointcut : JoinPoint 중 실제 Advice를 적용할 부분
4. Weaving : 그 시점에 공통 코드를 끼워넣는 작업
(컴파일 시 , 클래스 로딩 시 , 런타임 시 ) 가능
*Aspect = Advice + Pointcut : 실제동작코드 + 실제 적용된 부분 을 작성한클래스
=> 부가기능(로깅, 보안, 트랜잭션 등)을 나타내는 공통 관심사에 대한 추상적인 명칭)
=> 여러 객체에 공통으로 적용되는 부가기능을 작성한 클래스를 나타냄
=> 독립적인 요소로 구분해 내서 부가기능을 런타임 시 필요한 위치에 동적으로 참여하게 할 수 있다
Advice 시점에 따라
Before Advice | JoinPoint 앞에서 실행 |
Around Advice | JoinPoint 앞과 뒤에서 실행 |
After Advice | JoinPoint 호출이 리턴되기 직전에 실행 |
After Returning Advice | JoinPoint 메소드 호출이 정상적으로 종료된 후에 실행 |
After Throwing Advice | 예외가 발생했을 때 실행 |
*Proxy : 대상 객체에 Advice가 적용된 후 생성되는 객체
*Target Object : Advice를 삽입할 대상 객체
스프링은 대상 객체에 대한 프록시를 만들어 감싸서 대상 객체를 호출할 때 먼저 호출되서
Advice 로직을 처리한 후 대상 객체를 다시 호출한다.
[ AOP 구현 ] - *애너테이션 방식*
Spring pom.xml에 이미 aspectj 가 포함되어있음
+ 좀 더 쉬운 구현을 위한 Weaver 추가
***MVN Repository => Aspectj Weaver 추가
1. 해당 클래스에 @Aspect -> 공통 관심사가 작성된 클래스임을 명시
+(Advice, Pointcut 작성되어 있어야 함)
+@Conmonent 추가해 런타임 중 Advice코드가 동적으로 추가될 수 있도록 bean 등록
***servlet-context에서 namespace - aop 체크 + <aop:aspectj-autoproxy/> 작성 필요 ***
2. 수행할 메소드 + @Before / @After ...
*@Before("Pointcut") : Pointcut으로 지정된 메소드가 수행되기 전에 Advice 수행
**Pointcut 작성법 3가지
1) 직접
@Before("execution( * a.b.c..*Controller.*(..))")
작성식 : execution [접근제한자] +리턴타입 + 패키지경로명 + 클래스(*C : 모든 컨트롤러) + 메서드( *(..) : 모든 메서드)
-접근제한자는 생략가능/ *: 모든 리턴타입 의미 / .. : 하위 모든 패키지 or 0개 이상의 매개변수-
2) Pointcut이 작성된 메소드명을 작성
3) 타 클래스에 작성된 Pointcut 메소드를 작성
3. 메소드 작성
//@Before(직접작성)
@Before("PointcutCollection.controllerPointcut()")
public void controllerLog(JoinPoint jp) {
logger.info("테스트");
jp.getArgs() : 수행되는 메소드의 모든 매개변수를 배열로 얻어옴
jp.getTarget() : 타겟이 된 객체를 얻어온다
jp.getSignature() : 수행되려는 메소드 선언부를 얻어옴
{
-매개변수로 입력한 JoinPoint : 부가 기능 메소드를 제공하는 인터페이스
3-1 Pointcut을 모아둘 클래스
public class PointcutCollection {
@Pointcut("execution( 식 작성 )
public void controllerPointcut(){}
@Pointcut("execution( 식 작성2 )
public void servicePointcut(){}
}
++ Around 사용 -- 앞뒤 모두 아우르는 관점 ex) 러닝타임계산
@Aspect // Advice + Pointcut 공통 관심사가 작성된 클래스임을 명시
@Component
public class AroundAspect {
//slf4j import
private Logger logger = LoggerFactory.getLogger(AroundAspect.class);
//Around : 전처리, 후처리를 모두 해결하고자 할 때
//ProceedingJoinPoint를 매개변수 필수 사용
//(Proceeding: 진행)
//-> proceed() 메소드 사용 가능: 해당 메소드를 기준으로 Before, After 나뉨
@Around("PointcutCollection.serviceImplPointcut()")
public Object aroundLog(ProceedingJoinPoint pp) throws Throwable {
// 클래스명
String className = pp.getTarget().getClass().getSimpleName(); // 대상 객체의 간단한 클래스명(패키지명 제외)
// 메소드명
String methodName = pp.getSignature().getName(); // 대상 객체 메소드의 정보 중 메소드명을 반환.
String str = "";
str += "[Service]" + className + "-" + methodName + "()";
long startMs = System.currentTimeMillis(); // 서비스 시작 시의 ms 값
//구분기준
Object obj = pp.proceed();
long endMs = System.currentTimeMillis(); // 서비스 종료 시의 ms 값
//걸린시간
str+= "[Running Time]" +(endMs-startMs) + "ms";
//서비스 수행 시 사용된 파라미터
str+= "[Param]" + Arrays.toString(pp.getArgs());
logger.debug(str);
//proceed 반환값을 무조건 리턴
return obj;
}
}
Spring - 쿠키 전송(ex 로그인 시 아이디 저장) (0) | 2022.02.02 |
---|---|
Spring 스케줄러 (0) | 2022.01.14 |
SPRING MVC에서 Mybatis 활용 (0) | 2022.01.13 |
스프링 MVC - 이미지 업로드 / 파라미터 사용 DB삽입 (0) | 2022.01.11 |
스프링MVC - 트랜잭션 및 예외처리 (0) | 2022.01.06 |
Bean으로 등록하기 위한 스프링의 애너테이션
1. @Component : 객체(컴포넌트)를 나타내는 일반적인 타입으로 태그와 동일한 역할
2. @Repository : 퍼시스턴스(persistence) 레이어, 영속성을 가지는 속성(파일, 데이터베이스)를 가진 클래스
--EX) DAO
3. @Service : 서비스 레이어, 비즈니스 로직을 가진 클래스
--EX) Service
4. @Controller: 프리젠테이션 레이어, 웹 애플리케이션에서 View에서 전달된 웹 요청과 응답을 처리하는 클래스
(2,3,4 는 1의 구체화 형태인 셈)
DI 주입을 위한 스프링의 애너테이션
1. @Autowired : property, constructor-arg 태그와 동일한 역할을 한다 ,
의존하는 객체를 주입할 때 주로 Type을 이용하게 된다.
2. @Resource : 애플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용된다.
3. @Value: 단순한 값을 주입할 때 사용되는 어노테이션이다.
<context:component-scan> 태그
@Component를 통해 자동으로 Bean을 등록하고, @Autowired로 의존 관계를 주입받는 어노테이션을 클래스에서 선언하여 사용했을 경우에는 해당 클래스가 위치한 특정 패키지를 Scan 하기 위한 설정을 XML에 해주어야한다. 이 때 사용하는 태그이다
Spring 이론 (2) 스프링 동작 과 Bean / 싱글톤 패턴 (0) | 2022.01.16 |
---|---|
Spring 이론 (1) 스프링과 객체지향 (0) | 2022.01.07 |
Spring 개념정리(1) (0) | 2022.01.03 |
스프링 컨테이너: BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원한다.
스프링의 동작 구조 :
Request -> Servlet 컨테이너 -> Spring 컨테이너(new XmlWebApplicationContext()-> servlet-context.xml불러옴 )
*servlet-context.xml : spring 컨테이너가 실행해야 하는 내용을 설정하는 파일
(트랜잭션 관리, DI, AOP 등 관리)
즉,
1. 요청
2. 서블릿 컨테이너 - DispatcherServlet이 받음 (Web.xml 포함됨)
3. HandlerMapping ( 해당 요청을 매핑한 컨트롤러가 있는지 검색 -- @RequestMapping() 제공)
4. 처리 요청 +Bean등록
5. 결과를 출력할 View 리턴
6. DispatcherServlet에서 ViewResolver를 통해 view 검색 처리
[읽어들이는 순서]
-서버 구동시 web.xml 제일먼저 읽음
-그 안의 context-param 가장 먼저 읽음
-그 안에 root-context(자원관련 , DB ) / spring-security xml을 써놨고 제일 먼저 작동됨
-bean (스프링에서 생성하고 관리하는 객체) 으로 정의해놓음
-클라이언트가 요청시 dispatcher servlet 읽음 == 서블릿 컨테이너가 먼저 받음 ==> 스프링 컨테이너로 넘겨줌
-스프링 컨테이너의 servlet-context.xml의 설정대로 요청 받게됨 -> Handler Mapping ->
요청받은 주소를 처리할 클래스나 메서드에 지정하는 역할 (어노테이션 형식 사용) ==> @Controller, @RequestMapping 이 쓰임
-component-scan이 작동됨 -> 처리진행 -> 문자열 반환
-반환받은 문자열에 앞뒤 경로 붙여서 View Resolver 에서 응답 경로 내보냄
Bean?
-스프링이 IoC 방식으로 관리하는 객체 / 스프링이 직접 생성과 제어를 담당
<스프링 컨테이너와 스프링 빈> 작동 단계
1. 스프링컨테이너 생성
2. 스프링 빈 등록
3. 스프링 빈 의존관계 설정 준비
4. 스프링 빈 의존간계 설정 완료
<스프링 빈 조회 - 상속관계>
-> 부모타입으로 조회하면 자식타입도 모두 조회됨
<IoC컨테이너>
Bean 생성 객체 : BeanFactory <- ApplicationContext <- AnnotaionConfig ApllicationContext (상속)
BeanFactory :스프링 컨테이너 최상위 인터페이스 / 스프링의 IoC 담당하는 핵심
ApplicationContext : 팩토리 상속받아 빈 관리 + 부가기능위해 (실질적 사용)
* 스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일수 있게 설계됨
(애너테이션, XML)
HOW? BeanDefinition이라는 추상화 덕분에 여기서 메타정보만 가져오면 스프링 빈을 생성할 수 있다.
<싱글톤 패턴>
대부분의 스프링 애플리케이션은 웹 -> 여러 고객이 동시에 요청을 한다
==> 문제점 : 요청시마다 계속 객체 생성해줘야함 ==>메모리 낭비가 극심
--> 1개의 객체를 공유하도록 설계 == 싱글톤 패턴
싱글톤 패턴 : 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴
--> 2개 이상 생성을 막는다 == private으로 외부 new 막는다
==>스프링에선 자동으로 싱글톤 지원해줌
문제 :
1. 코드가 길어짐
2. 구체클래스에 의존한다 DIP 위반
3. == OCP 위반
4. 테스트 어려움
5. 유연성 떨어짐, 자식클래스 만들기 어려움
==> 스프링에서는 싱글톤 패턴 문제-> 싱글톤 컨테이너에서 해결함
싱글톤 컨테이너 : 싱글턴 패턴 적용 없이 싱글톤으로 관리
-> 스프링 컨테이너에서 관리.
-> 이미만들어진 객체를 공유해서 재사용
<싱글톤 방식의 주의점!!>
-> 상태를 유지하게 설계하면 안된다
== 만약 유저1일 100의 값을 넣은 상태에서 유저 2가 200의 값을 넣고 유저1이 값을 조회한다면?
==> 문제발생
<@Configuration> : 스프링의 싱글톤을 위해 존재한다
만약 두개의 bean에서 동일한 객체를 new로 생성한다면?각각 new 해야 맞지만 스프링이 싱글톤을 관리해줌 ==모두 같은 인스턴스가 공유되어 사용됨
HOW?
bean을 출력해보면 클래스 경로 + CGLIB를 붙혀버림 (상속 클래스를 하나 더 추가해서 조작함) => 이것이 유지해줌
1. 이미 스프링컨테이너에서 있으면? 스프링 컨테이너에서 반환
2. 아니면? 기존 로직을 호출해서 스프링 컨테이너에 등록하고 반환
-> @Configuration이 해주는 일이므로 @bean만 쓰면 싱글톤이 유지되지 않는다!
Spring 이론 (3) 스프링 애너테이션 (0) | 2022.01.16 |
---|---|
Spring 이론 (1) 스프링과 객체지향 (0) | 2022.01.07 |
Spring 개념정리(1) (0) | 2022.01.03 |