반응형

CompletableFuture와 리액티브 프로그래밍 컨셉의 기초

  • Thread, Future, 자바가 풍부한 동시성 API를 제공하도록 강요하는 진화의 힘
  • 비동기 API
  • 동시 컴퓨팅의 박스와 채널 뷰
  • CompletableFuture 콤비네이터로 박스를 동적으로 연결
  • 리액티브 프로그래밍용 자바 9플로 API의 기초를 이루는 발행 구독 프로토콜
  • 리액티브 프로그래밍과 리액티브 시스템

15.1 동시성을 구현하는 자바 지원의 진화

멀티코어 CPI에서 효과적으로 프로그래밍을 실행할 필요성이 커지면서 이후 자바 버젼에서는 개선된 동시성 지원이 추가됨.

자바는 Future를 조합하는 기능을 추가하면서 동시성을 강화

 

15.1.2 Executor와 스레드 풀

자바5는 Executor 프레임워크와 스레드 풀을 통해 스레드의 힘을 높은 수준으로 끌어올리는 즉 자바 프로그래머가 태스크 제출과 실행을 분리할 수 있는 기능 제공.

 

스레드의 문제

자바 스레드는 직접 운영체제 스레드에 접근한다. 운영체제가 지원하는 스레드 수를 초과해 사용하면 자바 애플리케이션이 예상치 못한 방식으로 크래시될 수 있으므르 기존스레드가 실행되는 상태에서 계속 새로운 스레드를 만드는 상황이 일어나지 않도록 주의해야 한다.

 

스레드 풀 그리고 스레드 풀이 더 좋은이유

자바 ExecutorService 는 태스크를 제출하고 나중에 결과를 수집할 수 있는 인터페이스를 제공한다.

워커스레드라 불리는 nThreads를 포함하는 ExecutorService 를 만들고 이들을 스레드 풀에 저장한다. 스레드 풀에서 사용하지 않은 스레드로 제출된 태스크를 먼저 온 순서대로 실행한다. 태스크 실행이 종료되면 이들 스레드를 풀로 반환한다.

장점은 하드웨어에 맞는 수의 태스크를 유지함과 동시에 수 천개의 태스크를 스레드 풀에 아무 오버헤드 없이 제출할 수 있다.

태스크(Runnable 이나 Callable) 를 제공하면 스레드가 이를 실행

 

스레드 풀 그리고 스레드 풀이 나쁜 이유

잠을 자거나 I/O를 기다리거나 네트워크 연결을 기다리는 태스크가 있다면 주의.

블록(자거나 이벤트를 기다리는)할 수 있는 태스크는 스레드 풀에 제출하지 말아야 한다.

 

15.1.3 스레드의 다른 추상화 : 중첩되지 않은 메서드 호출

  • 스레드 실행은 메서드를 호출한 다음의 코드와 동시에 실행되므로 데이터 경쟁 문제를 일으키지 않도록 주의해야한다.
  • 기존 실행 중이던 스레드가 종료되지 않은 상황에서 자바의 main() 메서드가 반환하면 

    - 애플리케이션을 종료하지 못하고 모든 스레드가 실행을 끝낼 때까지 기다린다.

    - 애플리케이션 종료를 방해하는 스레드를 강제종료 시키고 애플리케이션을 종료한다.

 

15.2 동기 API와 비동기 API

자바 5의 Future는 자바 8의 CompletableFuture로 이들을 조합하여 비동기 구현 가능

 

15.2.3 잠자기 는 해로운것으로 간주

10초 동안 워커 스레드를 점유한 상태에서 아무것도 안하는 코드

work1();
Thread.sleep(1000);
work2();

다른 작업이 실행될 수 있도록 허용하는 코드(스레드를 사용할 필요가 없이 메모리만 조금 더 사용)

work1();
scheduledExecutorService.schedule(ScheduledExecutorServiceExample::work2, 10, TimeUnit.SECONDS);

태스크가 실행되면 귀중한 자원을 점유하므로 태스크가 끝나서 자원을 해제하기 전까지 태스크를 계속 실행해야 한다.

태스크를 블록하는 것보다는 다음 작업을 태스크로 제출하고 현재 태스크는 종료하는 것이 바람직.

반응형
반응형

mockMvc 사용준비

@Autowired
SampleController sampleController;

private MockMvc mockMvc;

@Before
public void 기본() throws Exception{
	mockMvc = MockMvcBuilders.standaloneSetup(sampleController).build();

}

 

기본 get 방식 test

@Test
public void get_sample() throws Exception{
    RequestBuilder reqBuilder = MockMvcRequestBuilders.get("/test" + 1)
    .param("param1", param1)
    .param("param2", param2)
    .param("param3", param3);
    this.mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
}

post @requestBody 요청

public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

@Test
public void 제이슨_바디리퀘스트() throws Exception{
   RequestBuilder reqBuilder = MockMvcRequestBuilders.post("/test/" + 1)
                 .header("header1", header1)
                 .header("header2" , header2)
                 .contentType(APPLICATION_JSON_UTF8)
                 .content(requestJson);

   this.mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
}

메소드 사용법

andDO

요청에 대한 처리를 합니다. print() 메소드가 일반적입니다.

.andDo(print())

andExpert

예상값을 검증합니다. assert* 메소드들과 유사합니다.

// status 값이 정상인 경우를 기대하고 만든 체이닝 메소드 중 일부입니다.
.andExpect(status().isOk())
// contentType을 검증합니다.
.andExpect(content().contentType("application/json;charset=utf-8"))

andReturn

테스트 클래스에서 작성은 안했지만 테스트한 결과 객체를 받을 때 사용합니다.

MvcResult result = this.mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attributeExists("serverTime"))
.andReturn();
반응형
반응형

익스플로러 및 하위버젼의 브라우져를 제공하기 위해서는 polyfill 라이브러리 사용해야함.

npm install --save @babel/polyfill

위의 명령어로 설치하면 7버젼 이상이 설치됨.

babel-polyfill 은 6버젼

웹펙이 있으면

{
  entry: ['@babel/polyfill', './app.js'],
}

아니더라도 제일 entry point 에

import '@babel/polyfill'; 

추가하면 된다.

참고문헌

https://www.zerocho.com/category/ECMAScript/post/57a830cfa1d6971500059d5a

반응형

'프론트엔드' 카테고리의 다른 글

[webpack] webpack의 entry 사용법  (0) 2020.07.31
package.json 값 설명  (0) 2020.06.14
반응형

eventLister 제거시 같은 메소드를 사용해야 함.
콜백 메소드로
window.addEventListener('keyup', function(event) {
//~
})
다음 처럼 사용시 이벤트 제거가 안됨.
event 는 vue beforeDestroy 생성주기에 작성을 해야함. 안그러면 event 가 계속 살아 있음.

 mounted () {
    // let context = this
    window.addEventListener('keyup', this.doStuff) // enter 클릭시 alert 창 닫기
  },
  beforeDestroy () {
    window.removeEventListener('keyup', this.doStuff)
  },
  methods: {
    doStuff (event) {
      if (event.keyCode === 13) {
        this.callEvent()
      }
    },
    callEvent () {
      this.$emit('close')
    }
  }
반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

[vue] vue nuxt 시작하기  (0) 2020.08.17
[vue] vue skeleton 사용하기  (0) 2020.07.13
[Vue] vue eventbus 사용  (0) 2020.06.14
vue router  (0) 2020.06.14
vue checkbox 사용  (0) 2020.06.14
반응형

Vue EventBus

// 이벤트버스 생성
var EventBus = new Vue()
// 이벤트 발행
EventBus.$emit('message', 'hello world');
// 이벤트 구독
EventBus.$on('message', function(text) {
    console.log(text);
});

EventBus 를 전역으로 사용한다면 $off 도 등록을 해야함.
안하면 이벤트 구독이 계속 생겨나서 계속 이벤트가 발생됨.

참고문헌

http://vuejs.kr/jekyll/update/2017/02/13/vuejs-eventbus/

반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

[vue] vue skeleton 사용하기  (0) 2020.07.13
[Vue] vue eventlistener(이벤트리스너) 추가 제거  (0) 2020.06.14
vue router  (0) 2020.06.14
vue checkbox 사용  (0) 2020.06.14
vue 를 스프링부트 에서 연동  (0) 2020.06.14
반응형
import Vue from 'vue'
import Router from 'vue-router'
import ExampleRouter from './modules/example'

import Login from '@/components/common/Login'

import store from '@/vuex/store'

const requireAuth = () => (from, to, next) => {
  let auth = store.getters.getIsAuth
  if (auth) {
    return next() // isAuth === true면 페이지 이동
  }
  next('/') // isAuth === false면 다시 로그인 화면으로 이동
}
const loginDup = () => (from, to, next) => {
  let auth = store.getters.getIsAuth
  if (auth) {
    return location = '/main'
  }
  next()
}

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [{
    path: '/',
    name: 'login',
    beforeEnter: loginDup(), // 로그인 이후 '/' path 접근 redirect
    component: Login
    },
    ExampleRouter 
  ]
})

ExampleRouter 코드

/** When your routing table is too long, you can split it into small modules **/

import List from '@/components/List'
import Create from '@/components/Create'
import Detail from '@/components/Detail'

import store from '@/vuex/store'

const exampleRouter = {
  path: '/exam',
  component: User,
  redirect: '/exam/list',
  name: 'exam',
  children: [{
    path: 'list',
    component: List,
    name: 'list'
  },
  {
    path: 'create',
    component: Create,
    name: 'create'
  },
  {
    path: 'detail/:no',
    component: Detail,
    name: 'detail'
  }

  ]
}

export default exampleRouter
반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

[Vue] vue eventlistener(이벤트리스너) 추가 제거  (0) 2020.06.14
[Vue] vue eventbus 사용  (0) 2020.06.14
vue checkbox 사용  (0) 2020.06.14
vue 를 스프링부트 에서 연동  (0) 2020.06.14
vue cli 로 시작하기  (0) 2020.06.14
반응형

하나의 체크박스는 단일 boolean 값을 가짐
하지만, true false 외 다른값 가지도록 설정 가능

true 및 false 값 설정

:true-value="1" :false-value="0"

일반 예제

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> 
<input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> 
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> 
<br> 
<span>체크한 이름: {{ checkedNames }}</span> 
//checkedNames -> ["Jack", "Mike", "John"]
new Vue(
  { 
    el: '...', 
    data: { 
      checkedNames: [] 
      } 
    }
  )

참고문헌

https://takeuu.tistory.com/39

반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

[Vue] vue eventlistener(이벤트리스너) 추가 제거  (0) 2020.06.14
[Vue] vue eventbus 사용  (0) 2020.06.14
vue router  (0) 2020.06.14
vue 를 스프링부트 에서 연동  (0) 2020.06.14
vue cli 로 시작하기  (0) 2020.06.14
반응형

스프링부트 프로젝트 일단 생성

vue 프로젝트 생성

스프링부트 제일 상위 루트 terminal 에서 명령어 작성

vue-cli 2.X

vue init webpack frontend

vuecli-2.X시작하기

프로젝트 구조

├── src/ # Spring 소스코드 디렉터리
│ └── main/ │
│            ├── java/  
│            └── resources/  
│               ├── static/
│               ├── templates/
│               └── application.properties
├── target/ # Spring 빌드 디렉터리
│ └── ...
├── frontend/ # Vue.js 루트 디렉터리
│ ├── src/
│ └── ...
└── pom.xml

빌드

vue 빌드 파일 설정

파일명
frontend/config/index.js

build: {
  // Template for index.html
  index: path.resolve(__dirname, '../../src/main/resources/static/index.html'),
  // Assets Paths
  assetsRoot: path.resolve(__dirname, '../../src/main/resources/static'), }
cd frontend
npm run build

빌드를 하게되면 index.js 에서 설정해준 경로로 빌드된 파일이 떨어지고, 스프링부트를 실행해서 해당 static 파일 경로로 접속하면 화면이 뜬다.

3.X configure

vue.config.js 파일을 제일 상위 폴더 frontend 아래에 만든다.
assetsDir 폴더명이 outputDir 과 같아 static 이면 build 할때마다 해당 dir 파일 다 지우고 다시 만든다.
outputDir 가 root dir 이고, assetsDir 이 outputDir 하위에 생성되는 vue 에서 생성되는 build dir 이다.

//vue.config.js
module.exports = {
   assetsDir: "vuestatic",
  outputDir: "../src/main/resources/static",
  indexPath: "../templates/index.html",
  devServer: {
    proxy: "http://localhost"
  },
  chainWebpack: config => {
    const svgRule = config.module.rule("svg");

    svgRule.uses.clear();

    svgRule.use("vue-svg-loader").loader("vue-svg-loader");
  }
};

참고문헌

https://itstory.tk/entry/Spring-Boot-Vuejs-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0

반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

[Vue] vue eventlistener(이벤트리스너) 추가 제거  (0) 2020.06.14
[Vue] vue eventbus 사용  (0) 2020.06.14
vue router  (0) 2020.06.14
vue checkbox 사용  (0) 2020.06.14
vue cli 로 시작하기  (0) 2020.06.14

+ Recent posts