Log4j에서 Async 방식을 이용하려면 Properties 파일이 아닌 XML 형식으로 작성하여야 한다.


XML 방식을 이용하여 원하는 Append를 Async 방식으로 사용할 수 있게 해준다.


<appender name="asyncAppender" class="org.apache.log4j.AsyncAppender">
 <param name="BufferSize" value="500"/>
 <param name="Blocking" value="true"/>
 <appender-ref ref="something"/>
</appender>


XML 내부 설정 사항을 살펴보면 버퍼 사이즈 지정과 Block을 설정할 수 있다.


코드에서 Log를 사용하게 되면 Log내용을 메모리에 보관하였다가, Async 스레드가 메모리의 내용을


Appender에 전달하게 된다. (AsyncThread는 Log4j에서 자동으로 생성되어 동작함)


logger.info("INFO")

logger.debug("DEBUG")

...

 

 Memory

 AsyncThread


Append(File, Rolling etc..)



이와 같은 방식으로 사용되면, 순간적으로 많은 로그 요청으로 인하여 지정한 메모리 용량보다 많은 내용을


담게 될 수도 있다.


(예시: 웹 서비스에서 로그인 시간을 로그로 남긴다고 가정 하였을때, 버퍼 사이즈보다 많은 동시 접속자가


로그인을 시도하게 된다면, 로그의 버퍼사이즈보다 많은 내용을 순간적으로 가지게 된다.)



이 때, Blocking 설정이 True라면 메모리의 데이터가 해소 될때까지 메모리 용량에 유입을 막게 되고


Blocking 설정이 False라면 메모리가 확보 될떄까지 로그 내용은 버려지게 된다.


Blocking을 설정하지 않을 경우, 기본적으로 TRUE로 설정된다.





이클립스 사용 시, System.out을 사용하면 이클립스 콘솔 창에 결과가 출력이 된다.


하지만 필요에 따라, 콘솔이 아닌 파일로 출력해야 되는 경우에 간단한 방법으로 콘솔에서 파일로 출력 할 수 있다.



File file = new File("output.txt");
FileOutputStream fos = new FileOutputStream(file);
PrintStream ps = new PrintStream(fos);
System.setOut(ps);


위와 같은 방법을 사용하면, 해당 코드 이후로 System.out을 사용한 출력 결과는 output.txt 파일에 저장이 된다.



만약 파일에서 다시 콘솔로 출력해야된다면,


PrintStream console = System.out;
System.setOut(console);


위와 같이 사용하여, 파일에서 콘솔 출력으로 변경 할 수 있다.

Hikari Connection Pool 사용하기


Hikari Download




HikariCP Class 구현


public class HikariConnectionPool {
    private static HikariConnectionPool instance = null;
    private HikariDataSource ds;

    public HikariConnectionPool() {
        HikariConfig config = new HikariConfig();
        config.setDriverClassName("DRIVERCLASS");
        config.setJdbcUrl("JDBCURL");
        config.setUsername("USER");
        config.setPassword("PASSWORD");
        ds = new HikariDataSource(config);
    }

    public Connection getConnect(){
        Connection connection = null;
        try {
            connection = ds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    public static HikariConnectionPool getInstance(){
        if ( instance == null ){
            instance = new HikariConnectionPool();
        }
        return instance;
    }
}


HikariCP Driver Class Name은

https://github.com/brettwooldridge/HikariCP#popular-datasource-class-names

참조하여 사용.




장시간 동안 DB Connection에 요청이 없을 경우, connection이 종료되는 현상


로그상으로는 autoReconnection=true를 이용하라고 하지만, 실제로는 추천되는 방법이 아니다.


따라서 아래와 같은 설정을 통하여 connection이 종료되는 현상을 방지한다.



application.properties

spring.datasource.test-on-borrow=true

#mysql

spring.datasource.validation-query=SELECT 1

#oracle

spring.datasource.validation-query=select 1 from dual



자바 5에서 추가된 기능인 가변인자.


메소드의 인자값을 넣을때, 인수값의 개수가 일정하지 않을때 사용할 수 있는 기능.


-사용법


public void print(String... strings)


위와 같이 선언시에 ...을 넣으므로써 일정하지 않은 인수값을 모두 수용할 수 있게 된다.



-예시


public static void main( String[] args ){

     varargs("aa", "bb", "cc", "dd");


     varargs("11", "22");

}

public static void varargs(String... strings){

for( String str : strings){

System.out.println(str);

}

}



※ 유의점 : 자바 5 부터 사용 가능. 


앱에서 텍스트를 입력 받을 경우 키보드가 나타나지만, 입력이 완료되어도 사라지지 않는다.


따라서, 키보드를 감추기 위한 코드를 추가적으로 작성해주어야 하는데,


1. 리턴키를 입력받았을 경우


2. 백그라운드를 터치하여 입력을 종료하는 경우


위의 두가지 상황에 대한 코드를 추가를 해주는 것이 좋다.


키보드를 감추기 위해서는 resignfirstResponder 라는 메소드를 사용한다.


-(IBAction)textFieldReturn:(id)sender

{

[sender resignFirstResponder];

}

-(IBAction)backgroundTouched:(id)sender

{

[textField resignFirstResponder];

}




JavaScript파일은 .js를 사용하여 따로 작성하게 되는데, js파일 안에 js를 포함하는 경우가 생기기도 한다.


document.write('<script type="text/javascript" src=""></script>');


window.onload=function(){

외부 JS에 포함된 함수 호출

}


위와 같이 document.write를 사용하여 외부 JS파일을 포함시킬수 있다.


또한, 외부 JS 파일의 함수를 호출할 경우 onload이벤트를 이용하여 JS파일이 모두 파싱이 완료된 상태에서


함수를 호출해야 오류가 발생하지 않는다.





객체지향적인 프로그래밍에서는 상속이 매우 중요한 개념이다.


상속은 기본적으로 자식이 부모 클래스를 상속한다는 개념으로, 


부모클래스(Super Class)의 메소드와 인스턴스 변수를 자식클래스(Sub Class)가 모두 사용할 수 있다.


그러나, 자식클래스가 부모클래스의 메소드나 인스턴스 변수를 지울 수 없다.


인스턴스 변수는 추가만 가능하며,


메소드는 추가 또는 재정의가 가능하다.


그렇기 떄문에, 자식클래스를 사용하기 위한 필요성을 먼저 검토 해봐야 한다.


1. 클래스에 새 메소드나 인스턴스 변수를 추가해 기능을 확장하는 경우


2. 클래스의 특화된 버전을 만드는 경우


3. 하나 이상의 메소드를 재정의해 클래스의 기본 동작을 변경하려는 경우


위와 같이 3가지 경우에 따라 자식클래스로 상속받아 클래스를 확장해야 사용하면 된다.




먼저 구현하려는 로직은 아래와 같다.


ArrayList의 특정부분 부터 ArrayList의 마지막 부분까지 제거하려는 로직이였다.


for ( int i = k ; i < arrayList.size() ; i ++){

arrayList.remove(i);

}


이렇게 작성하였고, 에러는 발생하지 않는다.


문제는, 이와 같이 실행할 경우, ArrayList의 마지막 부분이 삭제되지 않게 된다.


이와 같은 문제점이 발생하게되는 원인은 


1. remove함수에 대한 이해 부족

2. for문의 동작 방식에 대한 이해 부족


2가지가 원인이 되겠다.


먼저, remove()는 해당 인덱스의 엘리먼트를 지워주는 함수로만 생각하였는데, 그 이후에 동작이 하나 더 있었다.


remove()이후에, 해당 인덱스 이후에 엘리먼트가 존재할 경우 인덱스값을 재계산한다는 것이다.


그리고, for문 동작 방식에 대한 이해는 remove와 연관시켜 생각해야되는데,


remove이후에 인덱스값이 재계산된 상태에서 


for의 동작방식에 따라 제일 마지막에 호출하게되는 부분이 size()함수이다.


그러므로 remove로 엘리먼트를 제거하고, 재계산된 size가 호출이되어 마지막 부분이 삭제가 되지 않는다.


이에 대한 해결 방법으로는 간단하게


removeRange()를 사용하거나,


size()함수의 값을 변수에 저장하여 값이 동적으로 변하지 않게 하면된다.



int end = arrayList.size();


for( int i = k; i < end ; i++){

arrayList.remove(i);

}





Ajax로 한글 데이터를 전송하게 되는 경우, 인코딩 문제로 인하여 한글데이터가 깨져서 전송이 된다.


이에 대한 해결 방법으로는 


톰켓 서버의 server.xml의 해당 포트의 


Connector 태그에서


URIEncoding="UTF-8"  을 추가해 준다.



예 )

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>