git의 branch는 특정 commit을 가리키는 바로가기 같은 것

비본 brance는 master로, git 저장소를 초기화 할때 자동으로 생성됨

HEAD라는 pointer는 현재 작업 중인 branch를 가리킴

 

 

Branch 생성

git branch Branch이름

* 가 있는 Branch가 현재 위치

 

Branch 이동

git checkout new_feature

 

 

master Branch와 비교

master에는 branch.txt라는 파일 없음

 

Merge하기

git merge Branch이름

git merge new_feature

'GIT' 카테고리의 다른 글

Github 연결  (0) 2020.04.14
Git 기본 사용법  (0) 2020.04.14

초기 사용자 설정

git config --global user.name "abc"
git config --global user.email "abc@abc.com"

 

현 Directory를 git 저장소로 만들기

git init

 

상태확인

git status

(추적 track : 특정 파일을 version관리 하도록)

 

stage에 추가

git add README 

커밋하기

git commit -m "initial commit"

 

작업내역

git log

 

특정파일 무시 : .gitIgnore 라는 파일에 무시할 내용 작성

vim .gitignore

 

 

원격 저장소 github 에서 프로젝트 다운받기

git clone http://github.com/jquery/jquery.git

'GIT' 카테고리의 다른 글

Github 연결  (0) 2020.04.14
Git Branch  (0) 2020.04.14

position으로 요소의 위치를 조정

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="css/position.css">
  <title>Document</title>
</head>
<body>
  <div class="a">a</div>
  <div class="b">b</div>
  <div class="c">c</div>
  <div class="d">d</div>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>

 

- position: static : 요소들의 자연스러운 흐름에 따라 원래 있을 자리에 배치, 기본값, 지정하지 않으면 그냥 이 상태임

- position: relative : 원래 있을 위치의 좌상단을 기준으로 이동

- position: absolute : 브라우저 화면의 좌상단을 기준으로 이동

- position: fixed : Scroll을 해도 항상 지정된 위치에 고정되어 있음, fixed의 경우, 위치 이동은 absolute처럼 적용됨

- position: sticky : 평소에는 static처럼 있다가 Scroll들의 화면 변화에 따라 지정된 위치에 고정됨

- left, top, bottom, right : 움직일 값 입력

- z-index : 요소들간의 z 축, 요소들끼리 겹치는 경우 위에 있을 요소를 결정함, static이 아닌 요소에 적용 가능

- 기본적으로 static이 아닌 요소가 static요소보다 위에 위치하고, 동등할 경우 나중에 나오는 요소가 위에 위치함

body {
  height: 10000px;
}

div {
  display: inline-block;
  width: 200px;
  height: 200px;
  opacity: 0.7;
}
.a {
  background: red;
}
.b {  
  position: relative;
  left: -60px;
  top: 10px;  
  z-index: 999;
  background: green;
}
.c {  
  position: absolute;
  left: 20px;
  top: 50px;
  background: blue;
}

.d {  
  position: fixed;
  left: 30px;
  top: 100px;
  background: orange;
}
p {  
  position: sticky;
  top: 50px;
  background: skyblue;
}


position설정시 부모요소와 자식요소 간의 관계

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="css/position.css">
  <title>Document</title>
</head>
<body>
  <div class="parent">
    <div class="child">
    </div>
  </div>
</body>
</html>

- 기본적으로 positon: absolute면 브라우저의 좌상단을 기준으로 움직이지만,

  부모요소가 static만 아니면, 자식에 positon: absolute를 지정하는 경우, 부모의 좌상단을 기준으로 움직임

 

- 부모가 position: fixed면 자식도 같이 고정됨

body {
  height: 10000px;
}

div {  
  display: inline-block;
  width: 200px;
  height: 200px;
}
.parent {
  /* position: fixed; */
  position: relative;
  left: 100px;
  top: 100px;
  z-index: 999;
  background: green;
}
.child {
  position: absolute;
  left: 50px;
  top: 10px;
  width: 50px;
  height: 50px;
  background: red;
}

'WEB > css' 카테고리의 다른 글

[CSS] flex  (0) 2020.04.12
[CSS] 가로배치방법 (display: inline-block, float: left)  (0) 2020.04.12

이전에 많이 사용하던 display: inline-block, float: left와 더불어 요소의 가로배치에 많이 사용되는 방법으로 브라우저 호환성은 아래와 같다. 기존의 방법에 비해 매우 간편하여, 최근 많이 사용됨

 

<!DOCTYPE html>
<html>
<head>
  <title>Document</title>
  <link rel="stylesheet" href="css/flex.css">
</head>
<body>
  <div class="container">
    <div class="item">AAA</div>
    <div class="item">B</div>
    <div class="item">CCCCCC</div>
    <div class="item">DDD</div>
    <div class="item">EEE</div>
  </div>
</body>
</html>

1. 부모 요소 flex

.container {  
  display: flex;  
  flex-direction: row;
  /* flex-direction: column; */

  justify-content: flex-start;
  /* justify-content: center; */
  /* justify-content: space-between; */
  /* justify-content: space-around; */
 
  align-items: stretch;
  /* align-items: center; */
  height: 80vh;
  background: gray;
}
.item {
  border: 1px solid black;
  background: white;
  font-size: 4em;
}

- 부모요소(.container)에 display: flex;지정

1) flex-direction: 자식 요소들을 정렬할 축을 지정 (row, column + reverse)

2) justify-content : 축에서의 요소 정렬 방법 (flex-start/end, center, space-between/around)

flex-direction: row; + 

3) align-items : 축의 위치를 정렬 (flex-start/end, center, stretch, baseline)

flex-direction: row; + 

* justify-content: center;  +  align-items: center;   =>  화면 중앙 정렬

 


2. 자식요소 flex

- 화면크기 변화에 따라 자식 요소의 크기를 유연하게 조정

- flex-grow: 숫자; 자식요소들이 축 방향에서 차지하는 비율을 조정 (요소의 width를 조정하는 것이 라니라, 콘텐츠의 너비를 제외한 여백을 조절하여 공간을 나눠가지게 함)

- 자식요소들이 부모의 공간을 모두 차지

- 일괄적용 : flow-grow: 아무 숫자;

- 개별 적용 : flow-grow: 해당 요소가 공간을 차지할 비율;

- flex-basis: 0;으로 지정하여 콘텐츠를 제외한 여백 대신, 요소 자체의 크기를 조절하게 해줌, 기본값은 auto

- flex: 1; = flex-grow: 1; + flex-basis: 0; + flex-shrink: 1;

.item {    
  /* flex-grow: 1;
  flex-basis: 0; */
  flex : 1;  
  border: 1px solid black;
  background: white;  
}
/* 
.item:nth-child(1) {flex-grow: 1}
.item:nth-child(2) {flex-grow: 5}
.item:nth-child(3) {flex-grow: 2}
.item:nth-child(4) {flex-grow: 3}
.item:nth-child(5) {flex-grow: 1} 
*/

'WEB > css' 카테고리의 다른 글

[CSS] position  (0) 2020.04.12
[CSS] 가로배치방법 (display: inline-block, float: left)  (0) 2020.04.12
<!DOCTYPE html>
<html>
<head>
  <title>Document</title>
  <link rel="stylesheet" href="css/reset.css">
  <!-- <link rel="stylesheet" href="css/01.css"> -->
  <!-- <link rel="stylesheet" href="css/02.css"> -->
  <link rel="stylesheet" href="css/03.css">
</head>
<body>
  <article class="page">
    <header class="page-header">
      <h1 class="page-title">페이지 제목</h1>
      <nav class="global-menu">
        <a href="#" class="global-menu-link">홈</a>
        <a href="#" class="global-menu-link">소개</a>
        <a href="#" class="global-menu-link">메뉴</a>
        <a href="#" class="global-menu-link">커뮤니티</a>
        <a href="#" class="global-menu-link">연락처</a>
      </nav>
    </header>
    <div class="content-container">
      <section class="content-section content-section-a">
        <p>Lorem ipsum dolor sit amet, consectetur.</p>
      </section>
      <section class="content-section content-section-b">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint cum sed facilis, est asperiores illum voluptatibus nihil. Corrupti iste, accusamus nam amet laborum. Vero ad architecto quos iure quis cumque assumenda corrupti similique praesentium eum a officiis, incidunt illum esse exercitationem rerum corporis ea reiciendis, voluptas eveniet adipisci beatae pariatur!</p>
      </section>
    </div>
    <footer class="page-footer">
      <p class="copyright">2020 &copy; 안녕?</p>
    </footer>
  </article>
</body>
</html>

1. display: inline-block

- display: inline인 요소는 요소를 Text문자로 취급, 문자의 Baseline을 따라서 정렬됨, width, height를 지정할 수 없음

- inline-block으로 지정해야 width를 가지게 되고 지정할 수 있음

- calc()을 사용하여 패딩 값을 뺀 값으로 width를 지정, css로 지정하는 width값은 패딩, 마진을 제외한 순수한 너비임

- <section>사이에 공백 문자가 있어서 clac()를 사용하여 너비를 조정해도 두 번째 <section>이 아래로 내려가 버림

≫ 부모(content-container)의 font-size를 0으로 해서 공백문자 공간을 없애버림 > inline특성에 따라 텍스트처럼 취급되는 <section>의 공간도 없어져 버리기 때문에 따로 font-size를 지정해줘야 함( font-size:1rem )

- font-size: 1rem : rem으로 <body> = root에 적용된 font-size에 비례 하여지정

.page-header {
  display: block;
  padding: 1em;
  background: pink;
}
.content-container {
  font-size: 0;  /*section사이의 공백문자 사이즈를 0으로*/
}
.content-section {
  display: inline-block; /*inline과 inline-block은 text로 생각*/
  vertical-align: top;
  padding: 1em;
  font-size: 1rem;  /* body의 font-size (디폴트 16px)를 사용*/
}
.content-section-a {
  background: yellow;
  width: calc(30% - 2em); /* 너비에서 좌우 1em 빼기 */
}
.content-section-b {
  background: skyblue;
  width: calc(70% - 2em);
}
.page-footer {
  padding: 1em;
  background: cyan;
}
.global-menu-link {
  display: block;
  background: white;
  margin: 5px;
}

 2. float: left

- 가로로 배치할 요소(.content-section)에 float: left를 지정

- 자식요소(.content-section)가 float설정으로 붕 뜨게 되어 부모요소(.content-container)가 화면에서 차지하는 공간이 사라져 버려서 다음 요소와의 배치가 이상해짐

부모요소가 끝나는 지점에 가상요소(.content-container::after)를 넣어서 float: left를 해제해주면 부모의 공간이 생김 (content:'' 를 넣어줘야 clear: both; 가 먹힘)

 

.page-header {
  display: block;
  padding: 1em;
  background: pink;
}
.content-container {  
  border: 3px solid red;
}
.content-container::after {  
  content: '';
  clear: both;
  display: block;
  height: 0;
  visibility: hidden;
}
.content-section {
  float: left;
   padding: 1em;
  font-size: 1rem;
}
.content-section-a {
  background: yellow;
  width: calc(30% - 2em);
}
.content-section-b {
  background: skyblue;
  width: calc(70% - 2em);
}
...

 

+ flex를 활용하는 방법 

'WEB > css' 카테고리의 다른 글

[CSS] position  (0) 2020.04.12
[CSS] flex  (0) 2020.04.12

<section>

하나의 주제로 그룹화된 컨텐츠

각 섹션의 주제는 섹션 요소의 하위 항목으로 제목을 넣어서 식별

 

<article>

다른 곳에서도 단독으로 사용이 가능한 내용

 

<header>

전체 콘텐츠를 아우르는 헤더

 

<footer>

전체 콘텐츠의 풋터

 

<nav>

사용자가 이용할 수 있는 링크의 모음

 

<aside>

웹 페이지의 주요 내용 흐름과 관련없는 내용

 

<h1 ~ h6>

각 섹션들의 제목으로 사용되며, 서브타이틀로는 사용X

 

 

<!DOCTYPE html>
<html>
<head>
  <title>Document</title>
  <link rel="stylesheet" href="css/reset.css">
  <link rel="stylesheet" href="css/01.css">
</head>
<body>
  <article class="page">
    <header class="page-header">
      <h1 class="page-title">페이지 제목</h1>
      <nav class="global-menu">
        <a href="#" class="global-menu-link">홈</a>
        <a href="#" class="global-menu-link">소개</a>
        <a href="#" class="global-menu-link">메뉴</a>
        <a href="#" class="global-menu-link">커뮤니티</a>
        <a href="#" class="global-menu-link">연락처</a>
      </nav>
    </header>
    <div class="content-container">
      <section class="content-section content-section-a">
        <p>Lorem ipsum dolor sit amet, consectetur.</p>
      </section>
      <section class="content-section content-section-b">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint cum sed facilis, est asperiores illum voluptatibus nihil. Corrupti iste, accusamus nam amet laborum. Vero ad architecto quos iure quis cumque assumenda corrupti similique praesentium eum a officiis, incidunt illum esse exercitationem rerum corporis ea reiciendis, voluptas eveniet adipisci beatae pariatur!</p>
      </section>
    </div>
    <footer class="page-footer">
      <p class="copyright">2020 &copy; 안녕?</p>
    </footer>
  </article>
</body>
</html>
AspectJ Weaver 라이브러리 추가

- Spring이 AOP 처리된 객체 생성 시 사용하는 라이브러리

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>${org.aspectj-version}</version>
</dependency>

 

AOP설정

root-context.xml > NameSpaces에서 aop, context체크

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	
	<context:annotation-config></context:annotation-config>
	<context:component-scan base-package="com.jjundol.aop.service"></context:component-scan>
	<context:component-scan base-package="com.jjundol.aop"></context:component-scan>	
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	
</beans>

- <component-scan>을 이용하여 com.jjundol.aop.service(Target), com.jjundol.aop(Advice)를 스캔 => Spring의 Bean으로 등록됨

- <aop:aspectj-autoproxy>를 이용하여 LogAdvice에 지정한 Advice관련 Annotation들이 동작함(@Before, @AfterReturning, @AfterThorwing, @Around)

 

Target JoinPoint 

SampleService 인터페이스

package com.jjundol.aop.service;
public interface SampleService {
	public Integer doAdd(String str1, String str2) throws Exception;
}

SampleServiceImpl.java

package com.jjundol.aop.service;

import org.springframework.stereotype.Service;

import lombok.extern.log4j.Log4j;

@Service
@Log4j
public class SampleServiceImpl implements SampleService {
	@Override
	public Integer doAdd(String str1, String str2) throws Exception {
		log.info("Target JointPoint : SampleServiceImpl > doAdd");
		return Integer.parseInt(str1) + Integer.parseInt(str2);
	}
}

 

Advice 작성

- 로그를 기록하는 일은 비즈니스 로직과는 상관없는 일이지만, 필요는 한 관심사임 Aspect

- Annotaion설정

- @Aspect : 해당 클래스 객체는 Aspect를 구현한 것임

- @Component : Spring에서 Bean으로 인식하도록

- @Before : JointPoint실행 전에 실행

- @AfterThrowing : Target이 예외를 발생한 후에 동작

- @Around : 직접 Target메서드를 실행할 수 있는 권한을 가지고 있고, 메서드 실행 전/후 처리가 가능

- 내부적으로  PointCut을 지정

- AspectJ 표현식 = PointCut : execution은 접근 제한자와 특정 클래스의 특정 메서드를 지정할 수 있음, 맨 앞의 * 은 접근 제한자, 맨 뒤의 * 은 클래스 이름과 메서드, args(....)로 파라미터 활용

package com.jjundol.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import lombok.extern.log4j.Log4j;

@Aspect
@Log4j
@Component
public class LogAdvice {

	@Before( "execution(* com.jjundol.aop.service.SampleService*.*(..))" )
	public void logBefore() {
		log.info("Advice @Before :  logBefore ============");
	}
	
	@Before( "execution(* com.jjundol.aop.service.SampleService*.doAdd(String, String)) && args(str1, str2)" )
	public void logBeforeWithParam(String str1, String str2) {
		log.info("Advice @Before : logBeforeWithParam str1 : " + str1);
		log.info("Advice @Before : logBeforeWithParam str2 : " + str2);
	}
	
	@AfterThrowing( pointcut = "execution(* com.jjundol.aop.service.SampleService*.*(..))", throwing = "exception" )
	public void logException(Exception exception) {
		log.info("Advice @AfterThrowing :logException Exception!" + exception);	
	}
	
	@Around( "execution(* com.jjundol.aop.service.SampleService*.*(..))" )
	public Object logTime(ProceedingJoinPoint pjp) {
		
		long start = System.currentTimeMillis();
		
		log.info("@Around Target : " + pjp.getTarget());
		log.info("@Around Param : " + pjp.getArgs());
		
		// invoke method
		Object result = null;
		
		try {
			result = pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
		long end = System.currentTimeMillis();
		
		log.info("@Around TIME : " + (end - start));
		
		return result;		
	}

}

 

AOP 테스트

1) 

* 외부에서의 호출은 Proxy객체를 통해 Target객체의 JoinPoint메서드를 호출하는 방식임

- 변수 service는 com.jjundol.aop.service.SampleServiceImpl의 객체((Target객체))가 아니라 Proxy의 인스턴스가 됨

- com.sum.proxy.$Proxy24는 dynamic-Proxy기법이 적용된 결과임

@RunWith(SpringJUnit4ClassRunner.class)
@Log4j
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class SampleServiceTest {
	
	@Autowired
	private SampleService service;
	
	@Test
	public void testClass() {
		log.info(service);
		log.info(service.getClass().getName());
	}
	
}
INFO : com.jjundol.aop.service.SampleServiceTest - com.jjundol.aop.service.SampleServiceImpl@432038ec
INFO : com.jjundol.aop.service.SampleServiceTest - com.sun.proxy.$Proxy24

2)

@Test
public void testAdd() {
  try {
  	log.info(service.doAdd("123", "567"));
  } catch (Exception e) {
  	e.printStackTrace();
  }		
}
INFO : com.jjundol.aop.LogAdvice - Advice @Before :  logBefore ============
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str1 : 123
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str2 : 567
INFO : com.jjundol.aop.service.SampleServiceImpl - Target JointPoint : SampleServiceImpl > doAdd
INFO : com.jjundol.aop.service.SampleServiceTest - 690

2-1) @Around 사용

- @Around가 먼저 동작하여 Target메서드와 파라미터를 알아낼 수 있고, proceed()를 통해 Advice메서드를 실행시킬 권한도 있음

- @Around메서드는 반환타임이 void가 아닌 타입으로 설정하고, 실행 결과 역시 직접 반환하는 형태로 작성해야 함

INFO : com.jjundol.aop.LogAdvice - @Around Target : com.jjundol.aop.service.SampleServiceImpl@5a3bc7ed
INFO : com.jjundol.aop.LogAdvice - @Around Param : [Ljava.lang.Object;@181e731e
INFO : com.jjundol.aop.LogAdvice - Advice @Before :  logBefore ============
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str1 : 123
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str2 : 567
INFO : com.jjundol.aop.service.SampleServiceImpl - Target JointPoint : SampleServiceImpl > doAdd
INFO : com.jjundol.aop.LogAdvice - @Around TIME : 5
INFO : com.jjundol.aop.service.SampleServiceTest - 690

 

3) @AfterThrowing, Target의 에러 발생 이후 실행되는 Advice

@Test
public void testAddError() throws Exception {
	log.info(service.doAdd("123", "abc"));
}
INFO : com.jjundol.aop.LogAdvice - Advice @Before :  logBefore ============
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str1 : 123
INFO : com.jjundol.aop.LogAdvice - Advice @Before : logBeforeWithParam str2 : abc
INFO : com.jjundol.aop.service.SampleServiceImpl - Target JointPoint : SampleServiceImpl > doAdd
INFO : com.jjundol.aop.LogAdvice - Advice @AfterThrowing :logException Exception!java.lang.NumberFormatException: For input string: "abc"

 

'WEB > spring' 카테고리의 다른 글

[Spring] 스프링/객체 지향 프로그래밍/다형성/SOLID  (0) 2021.03.16
Maven 프로젝트 생성  (0) 2020.04.28
AOP  (0) 2020.03.21
REST 예시  (0) 2020.02.27
HikariCP 커넥션 풀  (0) 2019.12.30

AOP

- Aspect-Oriented Programming, 관점 지향 프로그래밍

- 관점 = 관심사 = 개발을 하는 데 있어서 필요한 고민거리나 염두에 두어야 하는 작업

- 어플리케이션의 비즈니스를 수행하는 핵심적인 로직은 아니지만, 정상적인 동작을 위해서 고려하야 하는 내용들

 

- 관심사의 분리 : 관심사에 대한 코드를 매번 비즈니스 로직을 구현할 때 마다 반영하지 않고, 분리하여 개발한다.

- 개발자가 염두해야 하는 내용들을 관심사로 분리하여 만들어 놓고, 핵심 비즈니스 로직에는 해당하는 비즈니스 로직만 작성되도록 함 (관심사 + 비즈니스 => AOP => 관심사 / 비즈니스)

- 관심사는 핵심 로직을 수행하기 위한 사전 로직이나 사후 로직

 

* 관심사의 예시

- 나눗셈에서 나누는 수가 0인지 체크

 

- 비즈니스 로직의 코드와 관심사로 분리해 놓았던 코드를 컴파일or실행 시점에 결합시킴

- 실제 실행은 결합된 상태의 코드가 실행되므로, 개발자는 비즈니스 로직에 집중하여 코드를 작성하고, 어떤 관심사에 결합실킬지 확인하여 설정

 

- AOP를 적용하는 것은 기존의 코드를 수정하지 않고도 원하는 관심사를 엮을 수 있다는 것

 

- Aspect, Advice : Aspect는 관심사라는 추상적인 개념이며 Advice는 Aspect를 구현한 코드임

- Target : 순수한 비즈니스 로직

- JoinPoint : Target객체가 가진 여러개의 메서드

- PointCut : Target에는 여러개의 메서드(JoinPoint)가 있기 때문에 어떤 메서드와 결합할 것인지 결정하는 것, 관심사와 비즈니스 로직이 결합되는 지점을 결정하는 것

- Proxy : Target을 전체적으로 감싸는 존재, 내부적으로 Target을 호출할 때, 중간에 필요한 관심사를 거쳐서 Target을 호출하도록 자동/수동으로 설정됨, 스프링의 AOP기능을 이용하여 자동으로 생성되는 auto-proxy기능을 이용, 관심사와 메서드가 결합된 상태로 메서드를 호출하면 자동으로 관심사가 결합된 상태로 동작

=> 외부에서의 호출은 Proxy객체를 통해 Target객체의 JoinPoint메서드를 호출하는 방식임

Proxy

Advice는 동작 위치에 따라 구분됨

- Before Advice : Target의 JoinPoint실행 전, 코드의 실행 자체에는 관여 못함

- After Advice : 정상or예외발생 후 구분 없이 동작

- After Returning Advice : 모든 실행이 정상완료 후에 동작

- Afte Throwing Advice : 예외 발생 후에 동작

- Around Advice : 메서드 실행 자체를 제어, 직접 대상 메서드를 호출하고 결과나 예외를 처리

 

- Target에 어떤 Advice를 적용할 것인지 XMl을 이용한 설정 or Annotation으로 설정이 가능

- Target의 JoinPoint는 PointCut에 의해 Advice와 결합하여 원래 자신에게는 없는 기능을 가지게 됨

 

PointCut의 설정

- execution(@execution) : 메서드를 기준으로 설정

- within(@within) : 특정 타입(class)를 기준으로 설정

- this : 주어진 인터페이스를 구현한 객체를 대상으로 설정

- args(@args) : 특정 파라미터를 가지는 대상들만을 설정

- @annotation : 특정 어노테이션이 적용된 대상들만을 설정

'WEB > spring' 카테고리의 다른 글

Maven 프로젝트 생성  (0) 2020.04.28
AOP예시  (0) 2020.03.21
REST 예시  (0) 2020.02.27
HikariCP 커넥션 풀  (0) 2019.12.30
이클립스 프로젝트 JDBC 연결  (0) 2019.12.30

SampleControllerTests.java

package com.jjundol.controller;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.google.gson.Gson;
import com.jjundol.domain.Ticket;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({
	"file:src/main/webapp/WEB-INF/spring/root-context.xml",
	"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
@Log4j
public class SampleControllerTests {
	
	@Setter(onMethod_ = @Autowired)
	private WebApplicationContext ctx;
	
	private MockMvc mockMvc;
	
	@Before
	public void setup() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
	}
	
	@Test
	public void testConvert() {
		Ticket ticket = new Ticket();
		ticket.setBon(123);
		ticket.setGrade("Admin");
		ticket.setOwner("AAA");
		
		String jsonStrTicket = new Gson().toJson(ticket);
		
		log.info("testConvert.... : " + jsonStrTicket);
		// testConvert.... : {"bon":123,"owner":"AAA","grade":"Admin"}
		
		try {
			mockMvc.perform(post("/sample/ticket")
					.contentType(MediaType.APPLICATION_JSON)
					.content(jsonStrTicket))
					.andExpect(status().is(200));
			// /sample/ticket으로 JSON데이터를 전달, Gson : Java객체 -> JSON
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

SampleController.java

- @RestController : 해당 클래스는 REST 처리를 해주는 Controller임을 지정

- producer 속성 : 처리 결과로 반환해줄 데이터의 형식 지정

- ResponseEntity : 데이터 반환시 HTTP 상태값도 같이 반환하기 위한 용도

- @PathVariable : @GetMapping의 value의 { } 에 있는 내용을 파라미터로 받도록 처리

- @RequestBody() : json 형태의 데이터를 java 객체의 형태로 변환시켜줌

package com.jjundol.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jjundol.domain.SampleVO;
import com.jjundol.domain.Ticket;

import lombok.extern.log4j.Log4j;

@RestController
@RequestMapping("/sample")
@Log4j
public class SampleController {
	
    // /sample/getText
	@GetMapping(value = "/getText", produces = "text/plain; charset=UTF-8")
	public String getText() {		
		log.info("MIME TYPE: " + MediaType.TEXT_PLAIN_VALUE);		
		return "안녕하세요!?";
	}
	
    // /sample/getSample
	@GetMapping(value = "/getSample", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE,
												   MediaType.APPLICATION_XML_VALUE })
	public SampleVO getSample() {
		return new SampleVO(112, "스타", "로드");
	}
	
    // /sample/getSample2
	@GetMapping(value = "/getSample2")	// produces 속성은 생략가능
	public SampleVO getSample2() {
		return new SampleVO(113, "스타2", "로드2");
	}
	
    // /sample/getMap
	@GetMapping(value = "/getMap")
	public Map<String, SampleVO> getMap() {
		Map<String, SampleVO> map = new HashMap<String, SampleVO>();
		map.put("First", new SampleVO(114, "베이비", "그루트"));
		return map;
	}
	
    // /sample/check?height=177&wieht=65
	@GetMapping(value = "/check", params = { "height", "weight" })
	public ResponseEntity<SampleVO> check(Double height, Double weight) {
		
		SampleVO sample = new SampleVO(0, ""+height, ""+weight);
		
		ResponseEntity<SampleVO> result;
		
		if(height < 150) {
			result = ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(sample);
		} else {
			result = ResponseEntity.status(HttpStatus.OK).body(sample);
		}
		return result;
	}
	
    // /sample/product/bag/789
	@GetMapping(value = "/product/{cat}/{pid}")
	public String[] getPath(@PathVariable("cat") String cat, @PathVariable("pid") String pid) {
		return new String[] {cat, pid};
	}
	
    // /sample/ticket, json데이터를 처리(@RequestBody(json -> 객체))
	@PostMapping(value = "/ticket")
	public Ticket convert(@RequestBody Ticket ticket) {
		// JSON > 객체
		log.info("convert....Ticket" + ticket);
		// convert....TicketTicket(bon=123, owner=AAA, grade=Admin)
		
		return null;
	}
	
}

'WEB > spring' 카테고리의 다른 글

Maven 프로젝트 생성  (0) 2020.04.28
AOP예시  (0) 2020.03.21
AOP  (0) 2020.03.21
HikariCP 커넥션 풀  (0) 2019.12.30
이클립스 프로젝트 JDBC 연결  (0) 2019.12.30

커넥션 풀 : 매번 DataSource를 사용하여 연결하지 않고, 미리 연결을 맺어두고 반환하는 방식

 

1. pom.xml에 HikariCP추가

<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>2.7.4</version>
</dependency>

 

2. root-context.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
		<!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property> -->
		<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property>
		<!-- <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1522:jun"></property> -->
		<property name="jdbcUrl" value="jdbc:log4jdbc:oracle:thin:@localhost:1522:jun"></property>
		<property name="username" value="아이디"></property>
		<property name="password" value="패스워드"></property>
	</bean>
	
	<!-- HikariCP configuration -->
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<constructor-arg ref="hikariConfig"/>
	</bean>
	
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<context:component-scan base-package="com.jjundol.service"></context:component-scan>
	
	<mybatis-spring:scan base-package="com.jjundol.mapper"/>	
	
</beans>

 

- root-context.xml은 스프링이 로딩될 때 확인하는 설정 파일로, 이미 만들어져 있는 클래스들을 활용하여 스프링이 Bean으로 등록할 때 사용함 (hikariConfig, dataSource)

- 외부 jar를 활용하는 클래스들은 <bean>을 활용

'WEB > spring' 카테고리의 다른 글

Maven 프로젝트 생성  (0) 2020.04.28
AOP예시  (0) 2020.03.21
AOP  (0) 2020.03.21
REST 예시  (0) 2020.02.27
이클립스 프로젝트 JDBC 연결  (0) 2019.12.30