3월, 2017의 게시물 표시

(AngularJS) AngularJS 뷰란 무엇인가?

* AngularJS 가 DOM을 컴파일한 후에 존재하는 어떤것이다. * AngularJS의 컴파일 주기(cycle) 컴파일 단계와 링크단계의 두 단계로 구성된다. HTML이 로드되면 AngularJS는 DOM을 파싱하여 모든 AngularJS 디렉티브를 컴파일한다. 이 과정이 컴파일 과정이다. 일단, HTML을 구성하는 모든 항목이 구성되면 AngularJS는 링크단계(linking phase)에 접어든다. 이 단계에서는 AngularJS의 컴포넌트들을 적절한 스코프 인스턴스와 함께 연결하는 작업이 이루어진다. 컴파일과정은 백그라운드에서 계속되기 때문에 AngularJs 템플릿과 스코프 사이의 링크는 끊김없이 계속이어진다. 그러나 필요하다면 템플릿과 스코프를 함께 수동으로 컴파일 할 수도 있다. $compile(element.contents())(scope);

(MongoDB) DataType

이미지
1) Object_ID 관계형 데이터베이스의 ROWID와 유사한 속성이다. 하나의 도큐멘트(행)가 다른 도큐멘ㄴ트와 구별될 수 있는 유일한 값을 의미하며 RDBMS와 PRIMARY_KEY와 같이 유일하 값을 구성된다. * BSON의 ObjectID는 12Byte의 Binary값으로 구성되어 있다. * 하나의 Collection에 하나의 Document를 입력하면 반드시 유일한 값인 ObjectID가 부여된다. * MongoDB에서 제공하는 Default Object ID와는 별도로 사용자가 직접 Object ID를 부여할 수 있다.

(MongoDB) JSON과 BSON

* MongoDB에서 모든 데이터는 반드시 JSON타입으로 표현되지만 데이터베이스 내에 저장될 때는 BSON타입의 바이너리 형태의 데이터로 변환되어 저장된다. 예) { ename : "주종면"}

(MongoDB) 데이터 처리

1. Collection 생성과 원리 1) Collection의 생성 MongDB에는 두가지 타입이 있다. Capped Collecton 과 NonCapped Collectio 2가지가 있다. NonCapped Collection 은 관계형 데이터베이스의 테이블처럼 디스크 공간이 허용하는 범위내에서 데이터를 계속적으로 저장할 수 있는 타입이다. Capped Collection 은 최초 제한된 크기로 생성된 공간(익스텐트) 내에서 만 데이터를 저장할 수 있고 만약, 최초 공간이 모두 사용되면 다시 처음으로 돌아가서 기존공간을 재사용하는 타입이다. 기업에서 발생하는 데이터들 중에는 로그 데이터처럼 일정한 기간 내에서 만 저장, 관리할 필요가 있는 데이터들에게 효과적인 타입. * MongoDB에서는 JSON타입으로 데이터를 표현한다. >m={ ename : "smith"} * 데이터를 저장할 때 SAVE메소드를 사용한다. >db.things.save(m) * Collection에 저장된 데이터를 검색할 때 FIND메소드를 실행 >db.things.find() * 데이터를 입력할 때 Insert메소드를 사용한다. >db.things.insert({ empno : 1102, ename : "king"}) * Fort 문을 반복해 증가된 값을 n필드에 적용해 데이터를 저장한다. >for( var n = 1103; n<=1120; n++) db.things.save({n : n, m: "test"}) * Collection에서 조건을 만족하는 데이터를 검색 후 삭제 >db.things.remove({m:"test"}) * Save와 Update의 차이 ->Document단위로 변경하는 경우는 save가 효율적, Field단위로 변경할 경우 Update가 효율적이다. -> save 는 기존

(MongoDB) MongoDB 서버처리 간단 명령어

>mongod --dbpath c:\mongodb\test ----> MongoDB인스턴스 활성화 <Config파일로 시작하는 법> >notepad mongodb,conf <Mongo.EXE를 이용한 서버 접속> >mongo localhost:27017 >show dbs   --->데이터베이스 확인 >use test     ---> test 데이터베이스로 이동할 때 use 명령어를 사용하며 test데이터베이스가 존재하지 않은 경우 첫 번째 컬렉션을 생성할 떄 자동으로 생성된다. <호스트상태 정보와 논리적 구조확인> >db.stats() >db.hostInfo() <MongoDB 서버 종료> MongoDB를 ShutDown 할 떄도 반드시 admin 데이터베이스로 이동해서 db.shutdownServer() 명령어를 실행한다. >use admin >db.shutdownServer() <로그아웃만 하는법> >db.logout()

(MongoDB) 버전 주요 기능

2) MongoDB 3.0 버전 주요 기능 wiredTiger Storage Engine : 데이터 압축기능을 핵심으로 하는 트랜잭션 데이터의 효율적인 처리 중심의 MongoDB 저장 엔진 JavaScript Engine V2 : 여러개의 JavaScript 작업을 여러 개의 프로세스로 동시 처리해 주는 JavaScript Engine Compression & Encryption : 빅데이터 압축을 통한 저장 공간의 효율성 향상과 암호화를 통한 보안 기능 Validator & Auditing : 데이터의 무결성 보장을 위한 기능 Authentication : 수십~수백대의 서버 구축시 발생하는 보안 문제를 강화하기위한 인증 기술 Document-Level Lock : 데이터 처리를 위한 Lock 메커니즘 3) MongoDB 3.2 ~ 최근버전 주요기능 In-Memory Storage Engine : 인메모리 처리기술을 통한 데이터 처리 성능을 향상 시킬 수 있는 MongoDB 저장 엔진 OPS Manager : MongoDB를 효율적으로 관리할 수 있는 그래픽 모드의 관리 툴 Cloud Manager : Cloud 서버를 이용한 MongoDB의 백업 및 복구, 관리 기능 시각화 툴 : MongoDB 내의 데이터를 가공, 통계, 분석할 수 있는 시각화 기능

(MongoDB) 소개 및 용어

* JSON 데이터 표현 방식이다. * MongoDB는 Replication 기능과 Shard기능을 통해 복제 및 분산처리가 가능하 기능을 제공하며 MapReduce를 통해 빅 데이터에 대한 빠른 추출이 가능하다. *CRUD 위주의 다중 트랜잭션 처리도 가능하다. **메모리 매핑 기술을 통해 빅 데이터의 효율적 처리에 최적화된 메모리 인 데이터베이스 구조를 제공한다. MongoDB의 가장 큰 장점 중에 하나는 빅 데이터이 빠른 쓰기와 읽기 작업이 가능하다. 1) Table -> Collection (컬렉션) 2) Row -> Document(도큐멘트) 3) Column -> Field (필드) 4) Primary Key -> Object_ID Field(오브젝트 ID 필드) 5) RelationShip -> Embedded & Link (임베디드 & 링크)

(AngularJS) Angular.js Directive Scope Binding 전략

myDirective의 link로직에서 덮어씌운 값이 myCtrl에 있는 값에도 적용되는 것을 볼 수 있다. 즉, myDirective는 myCtrl의 스코프를 공용으로 사용한다. 그러나 scope속성을 true로 바꿀시 Directive는 별도의 스코프를 가지게 되어 myDirective에 넣어준 값이 myCtrl에는 적용되지 않는 것을 확인 할 수 있다. <Two-way Binding> Directive에서 별도의 Scope를 사용할 때에도 특정값을 바인딩 할 수 있다. 먼저 가장 많이 사용하게되는  = 는 Two-way Binding이다. 따라서 Directive내에서 값을 변경하게 된다면 그것이  원래 데이터에도 영향을 미치게된다. 물론, 원래 데이터를 변경하여도 그것을 사용하는 Directive에 영향을 미친다. 즉, 값의 동기화가 필요하다면 = 을 사용하면 된다. <Text Binding> 복잡한 객체 데이터나 동기화가 꼭 필요하지 않을 때는 @을 이용해 Text Binding을 사용할 수 있다. 그냥 attribute 값으로 직접 테스트를 입력해도 되지만, scope의 동적인 값을 넘길 때는 Interpolation expression {{}}과 함께 활용해야 한다. <&용법> &은 다른 녀석들과는 약간 다른 목적으로 사용된다. 별도의 Scope를 가지고 있는 Directive에서 부모 Scope로 특정한 값을 보내려면 Two-way Binding된 데이터를 그냥 바꾸는 방법 밖에 없는데, 만약 이 데이터를 다른 Controller나 Directive가 사용하고 있다면 어떤 사이드 이펙트가 나올지 모른다. 그런 경우 데이터 전달용으로 &을 사용할 수 있다. 위와같이 & 는 함수를 바인딩하는데에 사용된다. 바인딩한 함수의 매개변수를 통해 데이터를 전달할 수 있다. 특이한 점으로는 directive onSubmit()의

(AngularJS) deferred객체

약속이 지켜지거나 거절될 떄의 일을 정의하였으면 누군가는 약속을 지키거나 거절해야 한다. 이러한 일을 하는것이 바로 deferred 객체다. 약속을 만든사람이 약속을 거절하고 취소하듯이 deferred는 약속을 만들고 이 약속의 상태를 변경한다. AngularJS에서는 $q.defer(),를 이용해 deferred 객체를 생성할 수 있다.(deferred 객체의 생성은 곧 promise의 생성이기도 하다.) 참고하기 : http://programmingsummaries.tistory.com/345

(AngularJS) 라우팅

*사용자 관리나 사용자 스토리관리, 그리고 데이터 시각화 등 기능적인 측면에서 복잡도가 증가한다. 그렇다면 사용자를 표시할 때와 사용자 스토리를 표시할 때를 어떻게 구분할 수 있을까? 아마 가능한 모든 경우의 수를 고려해서 이를 처리하려면 꽤나 복잡한 코드가 될 것이다. 모든 웹 플리케이션은 URL을 가지고 있으므로 이를 잘 활용하면 애플리케이션의 상태를 정의할 수 있다. 즉, 실ㅈ 사용자가 보고자 하는 애플리케이션의 특정영역을 URL로 표현할 수 있다. 이런 기법을 URL 라우팅(routing)이라고 하며, AngularJS는 URL라우팅을 구현하기 위한 ngRoute서브 모듈을 제공한다. 라우트를 이용하면 애플리케이션의 URL을 기준으로 어떤 내용을 보이고 숨길 것인지를 결정할 수 있다. <ngRoute 구성요소> 1. $routeProvider : 라우트 설정 담당 2. $rotue : URL의 변경을 감지하여 ng-view 인스턴스를 제어한다. 3. ng-view : 현재 라우트를 처리할 컨트롤러와 뷰를 생성하고 제어 4. $routeParams : URL 매개변수를 해석하고 컨트롤러에 전달한다. ngView는 라우트 템플릿을 가져와 라우트의 컨트롤러 내에서 컴파일 한 후, 컴파일이 완료된 뷰를 사용자에게 표시하는 역할을 담당한다. * 복잡한 레이아웃 -> 라우트와 뷰 사이에는 1:1관계가 존재한다. 이 관계는 뷰가 중첩되는 등 복잡한 레이아웃을 구현할 경우 오히려 단점으로 작용한다. 이 문제를 해결하기 위한 방법은 AngularUI라우터를 이용 *라우트는 항상 모듈의 config블록에 작성한다. 그 이유는 애플리케이션이 실행되자마자 사용이 가능해야 하기 때문이다. <라우트에 매개변수 사용하기> 라우트 경로에는 콜론을 이용해서 :userID와 같이 이름이 지정된 매개변수 그룹을 정의할 수 있다. $route는 $location.path 속성을 통해 알아낸 경로에

(AngularJS) 프라미스

원격서버의 호출은 비동기 작업이기 때문에 응답이 리턴되는 시점을 보장할 수 없다. 그렇다면 특정 작업이 완료되는 시점을 알지 못하는 상황에서 어떻게 코드를 순서대로 실행할 수 있을까? 일단, 원격 서버를 호출한 뒤 리턴될 때까지 다른 작업을 수행할 수 있고, 호출이 리턴되었을 때 다시 원래 작업으로 돌아올 수 있다면 이는 정말로 환상적일 것이다. 프로미스 가 바론 그런 일을 하기 위한 도구다 Angular 1.3 은 단순히 .then()메소드만을 사용하는 것이 아니라 .then() .catch() .finally()문법을 통해 프로미슬르 해석하는 새로운 개념을 제시하고 있다. //가상 시나리오 myPromise()    .then(function(result){      //성공 콜백    })    .catch(function(error){     //에러 콜백    })    .finally(function(){     //결과에 관계없이 실행되는 콜백    });

(AngularJS) 서비스 생명주기

1. angular.module 객체가 제공하는 메소드 중 하나를 이용하거나 $provide 서비스를 직접 이용해서 서비스를 정의한다. 2. 컴파일 과정에서 서비스는 객체의 생성을 위해 인스턴스 팩토리에 등록된다. 3. 다른코드가 서비스 객체를 요청하면 $injector 서비스가 객체 인스턴스 캐시(instance cache)에 필요한 서비스 객체가 존재하는 지 확인. 만일 객체의 인스턴스가 존재하면 $injector 서비스는 캐시에 등록된 객체를 사용해 서비스가 필요한 곳에 주입. 캐시에 객체가 존재하지 않으면 $injector서비스는 인스턴스 팩토리에 새로운 객체를 요청한다. 이때 팩토리는 새로운 객체를 생성하여 리턴한 후 이 객체를 캐시에 저장해 이후의 객체 요청에 활용한다. <두 가지 중요한 점> 1. 서비스는 실제로 객체가 필요해지기 전까지 로드되지 않는다. 2. 오직하나의 인스턴스만이 생성되어 애플리케이션 내에서 싱글턴 객체로 활용된다.

(AngularJS) 사용자 정의 디렉티브(directive)

이미지
참고: http://www.nextree.co.kr/p4850/ 1. restrict HTML에서 디렉티브를 사용하기 위한 DOM엘리먼트 속성을 설정 -restrict규칙을 생략할 경우 'A'로 선언한 것과 같은 효과를 나타낸다. 2. template html의 디렉티브를 사용한 부분에 보여줄 내용으로 In-Line value를 설정. 3. templateUrl template을 별도의 html파일로 관리 -templateUrl에 선언한 url에 해당하는 HTML을 로드합니다. 이때, index.html 위치를 기준으로 로드할 html의 상대위치를 정의합니다. 4. replace 디렉티브를 사용한 HTML의 태그에 template 또는 templateUrl에 포함된 태그 내용을 추가할지 교체할지 설정 true로 설정할 경우 HTML의 디렉티브를 사용한 태그를 template 또는 templateUrl에 작성된 내용으로 교체합니다. 5. priority 디렉티브 별로 compile()과 link()의 호출 우선순위를 지정(기본값은 0) -priority 값이 클 수록 우선순위가 높고 먼저 호출된다. 6. transclude ng-transclude를 이용하여 template 또는 tempalteUrl 에서 디렉티브내의 원본내용을 포함시킬지 설정. true로 설정 시 디렉티브에 포함된 원본내용을 template의 ng-transclude를 사용한 곳으로 포함합니다. 7. scope 디렉티브의 scope를 설정 * 7. 1 scope옵션 scope : false -> 새로운 scope객체를 생성하지 않고 부모가 가진 같은 scope객체를 공유(default 옵션) scope ; true -> 새로운 scope객체를 생성하고 부모 scope 객체를 상속. scope: { ... } -> isolate/isolated scope를 새롭게 생성

(AngularJS)서비스

보통 서비스는 하나의 객체를 리턴하는 형태가 주를 이루는데 다양한 함수적인 기능을 수행하는 컨트롤러와는 상당한 차이가 있다. 컨트롤러는 $scope상의 모델을 조작하거나 UI와 밀접하게 여러 기능들을 수행한다. 반면 서비스는, 서비스 자체가 싱글톤이라는 특성을 사용해 컨트롤러간의 통신을 제어하거나, 리소스 접근 권한을 가진 객체를 리턴해서 컨트롤러에서 이 객체로 CRUD를 수행하거나 하는 방식으로 사용하게 된다. 서비스는 애플리케이션에 기능을 제공하며, 경우에 따라 애플리케이션이 의존하는 데이터를 표현하는 모델을 정의할 수도 있다. 그러므로 원격서버와 통신하면서 그 상태를 모델(Model)로서 관리하는 객체들이라면 서비스라고 부르기도 한다. app.service('nametrickService', function(){   this.reverse = function(name)   {     return name.split("").reverse().join("");   }; }); .service와 동일하게 사용할 수 있는 메소드로 .factory()라는 메소드가 존재한다. .factory()는 어떤 객체를 리턴하기 전에 몇 가지 코드를 실행할 수 있는 공간을 제공한다. 이런 특성을 활용해서 서비스와 동일하게 사용될 수 있게 된다. app.factory('nametrickFactory', function() { return {   reverse : function(name)   {     return name.split("").reverse().join("");   } } }); 지금까지 하나는 service로 하나는 factory로 서비스를 모듈에 등록했지만, 컨트롤러에 주입하기 전에는 실제로 사용할 수 없다. 초반에 선언했던 컨트롤러를 약간 수정해서 컨트롤러에 위에서 만든 서비스를 컨트롤러에 주입해보자.

(AngularJS) 모듈

이미지
1. 모듈을 이용한 컨트롤러 등록 모듈은 대체로 관련된 기능을 하나로 묶어 다른 코드와 결합도를 줄이고 재사용성을 높이기 위해 사용한다. 다음은 모듈 선언 코드이다. angular.module("모듈이름", ["사용할 모듈", ....]) ng-app ="ngBookmark" -> ng-app지시자에는 해당 앱이 사용하는 모듈의 이름을 값으로 줄 수 있다. .controller("bookmarkListCtrl", ['$scope',function($scope){ 이름이 'bookmarkListCtrl'인 컨트롤러 함수를 등록한다. angular.module()함수를 사용하면 그 반환 값으로 module인스턴스가 반환된다. 해당 인스턴스는 controller()함수를 이용해 컨트롤러를 등록할 수 있다. 2. 다른 모듈의 사용  ng-app에 해당 앱이 사용하는 모듈명을 값으로 주었습니다. 배열로 준 것이 아니라 하나의 값이 들어가므로 하나의 앱에서는 하나의 모듈만 사용할 수 있는 것처럼 보입니다. 재사용되는 코드의 단위를 좀 더 세세하게 쪼개어 여러 모듈로 만들고 싶을 때는 어떻게 할 수 있을까요? angular.module("ngBookmark", ["moduleA", "moduleB"]) 위와 같이 ngBookmark 모듈을 선언할 때 해당 모듈이 참조하는 moduleA와 moduleB를 선언하는 것입니다.  사실 우리가 사용하는 ng-repeat, ng-select와 같은 지시자와 곧 배울 $http, $log와 같은 서비스 모두 기본 모듈인 ng모듈에서 제공하는 것들이다. angular.module('cookieDemo', ['ngCookies']) -> 'cooki

(HTML) 메타(Meta)태그

* 메타 태그는 검색엔진에게 정보를 전달할 뿐만 아니라 웹 브라우저에게도 정보를 전달하는 역할을 한다.  문서의 초기정보 를 나타내는 속성은  http-equiv  속성이다. 이속성을 지정하면 문서의  기본언어 (content-language ) ,  MIME 타입 (content-type) ,   기본 스타일시트 (default-style ) ,   브라우저호환성설정 (X-UA-Compatible) ,  페이지 리로드 (refresh)   등을 나타낼 수 있다.  아래는 속성값에 대한 설명이다. 브라우저 호환 설정을 할 수 있는 X-UA-Compatible속성값이 있다. 이 속성값을 지정하면, 브라우저의 문서모드를 지정할 수 있다. 아래 같은 경우 IE=edge의 뜻은 최신버전으로 문서모드를 설정하라는 뜻이다. <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="refresh" content="5;url=http://www.homejjang.com/"> 홈페이지의 주소가 바뀌었을 경우에 사용하는 태그로 5초뒤에 url 속성값으로 지정한 페이지로 이동한다는 의미입니다.

(AngularJS) 디렉티브 내에서의 스코프 속성

ng-repeat 디렉티브의 매 인스턴스마다 새롭게 지역(local) 스코프 객체에는 특별한 속성들이 존재한다. $index, $first 그리고 $even 등의 속성이 바로 그것이다. <ul>  <li ng-repeat ="item in items"                       ng-click ="ctrl.currentIndex == $index">                          <h2> {{item.title}} </h2>                     <p ng-if ="ctrl.currentInedx == $index">                           {{item.longDescription}}                    </p>          </li> </ul>

(AngularJS) 단방향 데이터 바인딩

양방향 데이터 바인딩은 AngularJS가 가지는 강점 중 하나이지만,  이기능을 사용할 대는 메모리 문제 및 연산 오버헤드 문제가 발생하기도 한다. 이 문제를 해결하기 위해 컬렉션과 값이 오직 한 번만 평가될 수 있도록 표시할 수 있는 일회성 바인딩 기능을 제공한다. 일회성 바인딩을을 적용하려면 바인딩하려는 컬렉션이나 값 앞에 두 개의 콜론을 덧붙이면 된다. <ul class = "list my-repeat-animation"    ng-repeat="status in ::storyboard.statuses">    <h3 class ="status">{{::status.name}}</h3>

(AngularJs) 컨트롤러의 정의

1. 다이제스트 주기 -> AngularJS는 뭔가가 변경되었다는 것을 어떻게 알아채고 제때 수정할 수 있을까? 이 동작은 더티체크라는 개념위에 구현된 것이다. 더티체크란, 단순히 현재 값을 이전 값과 비교하여 값이 변경되었으면 이벤트를 발생시킨는 과정을 말한다. AngularJS는 $digest객체가 관리하는 다이제스트 주기를 통해 더티 체크를 수행한다. $digest 객체는 암암리에 동작하기 때문에 이 객체를 직접 호출하는 일은 없다. 다이제스트 주기를 시작하려면 $apply객체를 사용하면 된다. 이 객체는 $digest객체를 호출하며 오류처리 메커지므을 함께 탑재하고 있다. AngularJS는 컴파일 과정을 거치면서 $scope 객체에 정의된 모든 속성에 대해 감시(watch)표현식을 생성한다. 감시 표현식은 필요하다면 수동으로 생성할 수도 있지만, 컴파일 과정에서 생성되는 감시 표현식은 angular.equals메소드를 이용하여 속성값을 이전 값과 현재 값을 비교하는 간단한 함수다. $digest 주기 동안 스코프 객체의 모든 감시 표현식이 실행된다. 감시 표현식을 통해 $scope객체의 속성이 변경된 것을 알게 되면 리스너 함수가 호출된다. 간혹 AngularJS가 속성값이 변경되었다는 사실을 알아내지 못하는 경우도 있다. 이런 경우에는 $apply 객체를 통해 다이제스트 주기를 직접 실행할 수 있다. 4 대부분 API 호출이나 서드 파티 라이브러리가 수행한 작업을 AngularJS에게 알리고자 할 때 이 기법을 활용한다.

(트러블 슈팅)중요 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NullPointerException 예방하기

참고 : http://www.jpstory.net/2014/02/avoid-nullpointerexception/ <습관 들이기> 객체가 언제든 null일 수 있다는 판단하에 접근하면 도움이 될 것이다. 1. equals 메소드 사용시 문자열 비교시 non-null String 기준으로 비교합시다. equals 메소드는 symmetric하므로 a.equals(b) 와 b.equals(a) 가 동일하다. 그렇다면  null 일 수 있는 객체에서 equals메소드 호출은 피하는게 낫다 public void doSomething() {   //name이 null일 경우, NPE발생    if(name.equals("BAD")){     //do Something   } } public void doSomething(){    //name이 null이어도 NPE 발생 안함    if("BAD".equals(name)){      //do something     } } 다만 equals를 통과한 null 객체가 if문 안에서 메소드 호출등의 이유로 다시 사용된다면 동일한 NPE가 발생할 수 있습니다. 이럴경우는 미리 null 체크를 하는게 좋다. 2. toString()보다는 valueOf()를 사용할 것 1번 처럼 null 일 수 있는 객체에서 메소드 호출은 NPE발생 위험이 있겠죠? static으로 제공되는 valueOf()를 사용하면 null를 Parameter로 넘겨도 null return 할 뿐 NPE는 발생하지 않는다. (valueOf()는 String, Boxed Primitives 클래스(Integer, Double 등) 에서 static 메소드로 제공 됨) BigDecimal bd = getPrice(); System.out.println( String.valueOf(bd));  //NPE 발생 안함 System.out.println(

(자바 8) 바이너리 호환성, 소스 호환성, 동작 호환성

* 뭔가를 바꾼 이후에도 에러 없이 기존 바이너리가 실행될 수 있는 상황을 바이너리 호환성이라고 한다. (바이너리 실행에는 인증, 준비, 해석 등의 과정이 포함된다.) 예를들어 인터페이스에 메소드를 추가했을 때 추가된 메소드를 호출하지 않는 한 문제가 일어나지 않는데 이를 바이너리 호환성 이라고 한다. 간단히 말해, 소스호환성 이란 코드를 고쳐도 기존 프로그램을 성공적으로 재컴파일할 수 있음을 의미한다. 예를들어 인터페이스에 메소드를 추가하면 소스 호환성이 아니다. 추가한 메소드를 구현하도록 클래스를 고쳐야 하기 때문이다. 마지막으로 동작호환성 이란 코드를 바꾼 다음에도 같은 입력값이 주어지면 프로그램이 같은 동작을 실행한다는 의미이다. 예를들어 인터페이스에 메소드를 추가하면 프로그램에서 추가된 메소드를 호출할 일이 없으므로(혹은 우연히 구현 클래스가 이를 오버라이드했을 수도 있다) 동작 호환성은 유지된다.

(자바 8) 디폴트 메소드

* 디폴트 메소드는 주로 라이브러리 설계자들이 사용한다. * 디폴트 메소드가 없던 시절에는 인터페잇에 메소드를 추가하면서 여러 문제가 발생했다. 인터페이스에 새로 추가된 메소드를 구현하도록 인터페이스를 구현하는 기존 클래스를 고쳐야 했기 때문이었다. 본인이 직접 인터페이스와 이를 구현하는 클래스를 관리할 수 있는 상황이라면 이 문제를 어렵지 않게 해결할 수 있었지만 인터페이스를 대중에게 공개했을 떄는 상황이 다르다. 그래서 디폴트 메소드가 탄생한 것이다. 우리가 라이브러리 설계자라면 기존 구현을 고치지 않고도 인터페이스를 바꿀 수 있으므로 디폴트 메소드를 잘 이해하는 것이 중요하다. * 우리가 만드는 인터페이스에도 디폴트 메소드를 추가할 수 있따. <디폴트 메소드 활용패턴> 1. 선택형 메소드 ->자바8이전에는 Iterator에 remove메소드가 비어있었다. 하지만  자바 8의 Iterator인터페이스는 remove메소드를 정의한다. 기본 구현이 제공되므로 Iterator인터페이스를 구현하는 클래스는 빈 remove메소드를 구현할 필요가 ㅇ벗어졌고, 불피요한 코드를 줄일 수 있다. 2. 동작 다중 상속 ->자바에서 클래스는 한 개의 다른 클래스만 상속 할 수 있지만 인터페이스는 여러개 구현할 수 있다. 디폴트 메소드를 이용하면 다중상속이 가능해진다. * 다른 클래스나 인터페이스로부터 같은 시그니처를 갖는 메소드를 상속받을 때 <알아야 할 세 가지 해결 규칙> 1. 클랫가 항상 이긴다. 클래스나 슈퍼클래스에서 정의한 메소드가 디폴트 메소드보다 우선권을 갖는다. 2. 1번 규칙 이외의 상황에서는 서브 인터페이스가 이긴다. 상속관계를 갖는 인터페이스에서 같은 시그니처를 갖는 메소드를 정의할 때는 서브인터페이스가 이긴다. 즉, B가 A를 상속받는다면  B가 A를 이긴다. 3. 여전히 디폴트 메소드의 우선순위가 결정되지 않았다면 여러 인터페이스를 상속받는 클래스가 명시적으로

(자바 8) 실행 어라운드 패턴.

자원처리 (예를들면 데이터베이스의 파일처리)에 사용하는 순환패턴은 자원을 열고, 처리한 다음에, 자원을 닫는 순서로 이루어진다. 설정과 정리과정은 대부분 비슷하다. 즉, 실제자원을 처리하는 과정은 설정과 정리 두 과정이 둘러싼 형태를 갖는다. 예를들어) 작업 A, 작업 B를 한다치면 1. 초기화/준비코드 -> 작업 A -> 정리/마무리코드 2. 초기화/준비코드 -> 작업 B -> 정리/마무리코드 즉, 이러한 것을 실행어라운드 패턴이라 부른다. 그러나 작업 A, 작업 B를 실행하기 위해서는 위와같이 중복되는 준비 코드와 정리코드가 발생한다. 이를 줄이기 위한 것이다. 이 패턴은 총 4단계를 거친다. 1단계 : 동작파라미터화를 기억하라. 2단계 : 함수형 인터페이스를 이용해서 동작 전달 3단계 : 동작 실행! 4단계 : 람다 전달 public static String processFile() throws IOException{    try(BufferedReader br = new BufferedReader(new FileReader("data.txt"))){      return br.readLine();    } } 1단계 : 동작파라미터화를 기억하라. -> 위 코드는 파일에서 한 번에 한 줄만 읽을 수 있다. 만약 한 번에 두 줄을 읽거나 가장 자주 사용되는 단어를 반환하려면 어떻게 해야 할까? processFile의 동작을 파라미터화하는 것이다. 람다를 이용해서 동작을 전달할 수 있다. String result = processFile((BufferedReader br) -> br.readLine() + br.readLine()); 2단계 : 함수형 인터페이스를 이용해서 동작 전달 함수형 인터페이스 자리에 람다를 사용할 수 있다. 따라서 BufferedReader -> String 과 IOException을 던질 수 있는 시그너처와

Simple Spring Memcached(SSM)

참고 : http://m.blog.naver.com/tmondev/220725135383

(자바 8) null 대신 Optional

예를들어 어떤사람이 차를 소유하고 있지 않다면 Person 클래스의 car 변수는 null를 가져야 한다. 하지만 새로운 Optional 을 이용할 수 있으므로 null를 할당하는 것이 아니라 변수형식을 Optional<Car>로 설정할 수 있다. * Optional 이란? Optional<T> 클래스 (java.util.Optional)는 값의 존재나 부재 여부를 표현하는 컨테이너 클래스다. 예를들어 Optional<Dish> 에서느 요리명이 null 인지 검사할 필요가 없었다. menu.stream() .filter(Dish::isVegetarian) .findAny() .ifPresent(d -> System.out.println(d.getName());

(하이버네이트) @EntityListeners

<Entity Listener 란?> 엔티티를 DB에 적용하기 이전 이후에 커스텀 콜백을 요청할 수 있는 어노테이션이다. 예를들어 아래와 같이 업데이트 이전에 Account.lastDate를 교체해 줄 수 있다. public class AccountListener {   //업데이트 이전  @PreUpdate   //Account 클래스 에서 작동.   void onUpdate(Account account)   {    account.setLastDate(new Date());   } } 그리고 Account 클래스는 다음과 같이 추가해준다. // {}를 사용하여 복수개의 클래스르 지정할 수 있다. @EntityListeners(AccountListener.class) //생략 public class Account {    //생략 } 이렇게 하면 update 가 일어나기 전에 Account.lastDate를 현재시간으로 바꾸어주게된다.

(자바8) 스트림 활용

<필터링과 슬라이싱> 1. 프레디케이트로 필터링 -> filter 메소드는 프레디케이트(불린을 반환하는 함수)를 인수로 받아서 프레디케이트와 일치하는 모든 요소를 포함하는 스트림을 반환한다. 예) List<Dish> vegetarianMenu = menu.stream()                                                .filter(Dish::isVegetarian) //채식 요리인지 확인하는 메소드레퍼런스                                                . collect(toList()); 2. 고유요소 필터링 -> distinct라는 메소드 (hashCode, equals로 결정) List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 4, 5); numbers.stream() .filter(i -> i % 2==0) .distnct() .forEach(System.out::println); 3. 스트림축소 -> limit 4. 요소 건너뛰기 -> skip(n) <매핑> 스트림 API 의 map과 floatMap메소드는 특정 데이터를 선택하는 기능을 제공 List<Integer> dishNameLengths = menu.stream()                                                      .map(Dish::getName)                                                      .map(String::length)                                                      .collect(toList()); <스트림의 평면화> * flatMap 예)  List<Str

(자바8) 스트림

* 많은 요소를 포함하는 커다란 컬렉션의 처리? ->성능을 높이려면 멀티커오 아키텍처를 활용해서 병렬로 컬렉션의 요소를 처리해야 한다. * 컬렉션과 스트림의 가장 큰 차이 -> 데이터를 언제 계산하느냐가 컬렉션과 스트림의 가장 큰 차이이다. 컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조. -> 반면 스트림은 이론적으로 요청할 때만 요소를 계산하는 고정된 자료구조. <스트림이란 무엇인가?> 스트림을 이용하면 멀티 스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리하는 것 * 스트림에 filter, map, limit, collect로 이어지는 일련의 데이터처리 연산을 적용한다. collect를 제외한 모든 연산은 서로 파이프라인을 형성할 수 있도록 스트림을 반환한다. <filter> 람다를 인수로 받아 특정 요소를 제외시킨다.  예) d -> d.getCalories() >300 <map> 람다를 이용해서 한 요소를 다른 요소로 변환하거나 정보를 추출한다. Dish::getName(람다표현식으로는 d -> d.getName()) <limit> 정해진 개수 이상의 요소가 스트림에 저장되지 못하게 스트림 크기를 축소한다. <collect> 스트림을 다른형식으로 변환한다. <외부반복과 내부 반복> 컬렉션은 외부반복, 스트림은 내부반복이다. 1.  컬렉션 for-each루프를 이용한 외부반복 예) List<String> names = new ArrayList<String>(); for(Dish d: menu){   names.add(d.getName()); } 2. 스트림 내부반복 List<String> names = menu.stream()            

(REST JWT) 소개

이미지
Claim기반 토큰의 개념  API나 서비스를 제공하는 서버 입장에서 그 access_token을 통해서 사용자에 연관된 권한(예를 들어 scope같은 것)을 식별한 뒤 권한을 허용해주는 구조이다. 즉 서비스를 제공하는 입장에서는 토큰을 가지고 그 토큰과 연관된 정보를 서버쪽에서 찾아야 한다. (사용자 ID나 권한등). JWT는 Claim 기반이라는 방식을 사용하는데, Claim이라는 사용자에 대한 프로퍼티나 속성을 이야기 한다. 토큰자체가 정보를 가지고 있는 방식인데, JWT는 이 Claim을 JSON을 이용해서 정의한다. 다음은 Claim을 JSON으로 서술한 예이다.이 JSON 자체를 토큰으로 사용하는 것이 Claim 기반의 토큰 방식이다. {   "id":"terry"   ,"role":["admin","user"]   ,"company":"pepsi" } <코드 1. JSON으로 Claim을 기술한 토큰의 형태 > 자 그렇다면, 이러한 Claim 방식의 토큰은 무엇이 좋을까? 이 토큰을 이용해서 요청을 받는 서버나 서비스 입장에서는 이 서비스를 호출한 사용자에 대한 추가 정보는 이미 토큰안에 다 들어가 있기 때문에 다른 곳에서 가져올 필요가 없다는 것이다. “사용자 관리” 라는 API 서비스가 있다고 가정하다.  이 API는 “관리자(admin)” 권한을 가지고 있는 사용자만이 접근이 가능하며, “관리자” 권한을 가지고 있는 사용자는 그 관리자가 속해 있는 “회사(company)”의 사용자 정보만 관리할 수 있다. 라고 정의하자 이  시나리오에 대해서 일반적인 스트링 기반의 토큰과 JWT와 같은 Claim 기반의 토큰이 어떤 차이를 가질 수 있는 지 알아보도록 하자. OAuth 토큰의 경우 <그림 2. String 토큰에 의한 API