'JAVA'에 해당되는 글 76건

  1. 2009.05.06 :: 스프링 Controller
  2. 2009.05.06 :: 스프링MVC
  3. 2009.05.06 :: 스프링 DI (2.5)
  4. 2009.05.06 :: 스프링 AOP (2.5)
  5. 2009.05.06 :: [DataBase] Connection Pool
  6. 2009.05.06 :: [Spring] XML 네임스페이스
  7. 2009.05.06 :: 스프링MVC 개발단계
  8. 2009.05.06 :: Spring AOP - 4 (POJO 기반 Aspect)
  9. 2009.05.06 :: Spring AOP - 3 (@AspectJ 애스펙트 이용한 오토프록싱)
  10. 2009.05.06 :: Spring AOP - 2 (Classic AOP)
  11. 2009.05.06 :: 스프링 AOP - 1
  12. 2009.05.06 :: 스프링 DI - 2
  13. 2009.05.06 :: 스프링 DI - 1
  14. 2008.08.24 :: swing
  15. 2008.08.19 :: FoucsListener 구현하기
  16. 2008.08.15 :: 자바 날짜 형식
JAVA/SPRING 2009. 5. 6. 12:00



컨트롤러 부분은 깊게 공부하지 않았다.
이거 일일이 진지하게 파헤쳐보려다간 시간을 너무 많이 날릴 수 있으므로... 충분히 실제 코딩하면서 레퍼런스할 정도로 공부해 두면 되겠다.


컨트롤러 클래스 분류




컨트롤러 부분은 어렵다.(무엇인들 어렵지 않을까..)
목적에 맞게 컨트롤러르 구현하자. 물론 책을 잘 참조해서,.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:58



1.클라이언트의 요청이 DispatcherServlet에 전달
2.DispatcherServlet은 HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체를 구한다
3.DispatcherServlet은 컨트롤러 객체의 handleRequest()메소드를 호출하여 클라이언트 요청 처리
4.컨트롤러의 handleRequest()메소드는 처리결과 정보를 담은 ModleAndView객체를 리턴
5.DispatcherServlet은 viewResolver로부터 응답 결과를 생성할 뷰 객체를 구한다.
6.뷰는 클라이언트에 전송할 응답을 생성

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <display-name>
 SpringTest</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
 
 <servlet>
  <servlet-name>
   dispatcher
  </servlet-name>
  <servlet-class>
   org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>
   dispatcher
  </servlet-name>
  <url-pattern>*.htm
  </url-pattern>
 </servlet-mapping>

 
</web-app>

dispatcher-servlet.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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!--핸들러-->
<bean id = "handlerMapping"
 class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name = "/hello.htm"
 class = "kame.spring.chap04.HelloController" />
<bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/view/" />
  <property name="suffix" value=".jsp" />
 </bean>  
</beans>

web.xml에 DispatcherServlet설정과 어플리케이션 컨텍스트 설정
.hml으로 들어오는 클라이언트의 요청을 DispatcherServlet이 처리하도록 설정.
DispatcherServlet은 WEB-INF/에 위치한 [서블릿이름]-servlet.xml파일을 설정 파일로 사용

package kame.spring.chap04;
import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloController extends AbstractController{
 @Override
 protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("hello");
  mav.addObject("greeting",getGreeting());

  return mav;
 }
 private String getGreeting(){
  int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
  if(hour >= 6 && hour <= 10){
   return "좋은아침";
  }else if(hour > 12 && hour <= 15){
   return "점심해써?";
  }else if(hour >= 18 && hour <= 22){
   return "좋은밥";
  }
  return "안녕하세요";
 }
}

처리결과를 ModelAndView에 담아 DispatcherServlet에 전달. ModelAndView는 컨트롤러의 처리결과에 대한 응답 화면을 생성할 뷰 정보저장.

<bean id = "handlerMapping"
 class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name = "/hello.htm"
 class = "kame.spring.chap04.HelloController" />


BeanNameUrlHandlerMapping은 URL과 일치하는 이름을 갖는 컨트롤러를 사용. http://localhost/contextpath/hello.htm으로 요청이 들어올 경우, 이름이 "/hello.htm"인 컨트롤러를 이용하여 클라이언트의 요청을 처리한다.

처음해보면서 안되었는데... 톰캣의 server.xml 올바르게 잡고,, 소스 오타수정 모두 하고.. 모두 완벽했었는데 안되었다.
http://localhost/spring/view/hello.htm 주소창에 요렇게 치니까 404에러... 톰캣에서 docBase를 WebContent까지 패스에 잡아주었으므로 WebContent폴더 안에 있는 view폴더부터 쓰는것이 당연하다.. view에 있는 hello.jsp로 직접 접근하니 되었는데...(물론 매핑이 안되서 결과물은 안나왔다..)
안되서... 예제도 설치해서 해봤는데.. 예제는 이상한 에러 쫘악... 별짓다해봤다.. 자바버전도 수정해보고 폴더를 옮겨보기도 했는데...
어쨌든 해결했는데.... 주소창에
http://localhost/spring/hello.htm 로 view폴더를 빼고 치니까 되는거다!!. 프레임워크니까!! 괜히 프레임워크겠어!! spring이 톰캣에 설정한 패스이름이다.... 결론은 폴더고 나발이고간에 xml에 설정해놓으면 패스명/xxx.htm하면 되는거다!!

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>인사</title>
</head>
<body>
인사말 " <strong>${greeting}</strong>
</body>
</html>
신기한것은 스트럿츠2처럼 태그라이브러리를 상단에 정의해주지 않았는데도 요 $ 태그가 먹힌거..(요걸머라고하나..) 왜인지는 모른다..
 
mav.setViewName("hello");

뷰이름을 가지고 viewResolver가 이 이름을 이용하여 알맞은 view객체를 선택한다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:55


스프링 컨테이너의 주요 인터페이스


1.1 BeanFactory인터페이스 

org.springframework.beans.factory.BeanFactory는 빈 객체를 관리하고 각 빈 객체 간의 의존 관계를 설정해 주는 기능을 제공.
XmlBeanFactory클래스가 구현.
Resource인터페이스를 사용하여 다양한 종류의 자원을 동일한 방식으로 표현.
Resourcce res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
ParserFactory factory = (ParserFactory)factory.getBean("parserFactory");

특정 리소스로부터 설정 정보를 읽어와 XmlBeanFactory객체를 생성한 뒤에는 getBean()메소드를 이용하여 알맞은 빈을 가져와 사용하면 된다.

1.2 ApplicationContext , WebApplicationContext 인터페이스
빈팩토리인터페이스를 상속받은 인터페이스로서 빈팩토리가 제공하는 빈 관리 기능 이외에 파일과 같은 자원처리추상화, 메시지 지원 및 국제화지원, 이벤트 지원등 추가적인 기능을 제공하고 있다. BeanFactory보다 ApplicationContext 구현 클래스르 주로 사용한다.

빈(Bean)의 생성과 의존관계 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">


<bean id = "writeArticleService"  class = "kame.spring.chap02.WriteArticleServiceImpl" >
    <constructor-arg>
        <ref bean = "articleDao" />
    </constructor-arg>

</bean>

<bean id = "articleDao" class = "kame.spring.chap02.OracleArticleDao" >
</bean>


bean의 id는 객체명이다. class는 이 객체를 참조하는 클래스가 있는 경로를 써주면 된다.
생성자를 통해 의존하는 객체르 전달받는 경우 <constructor-arg>태그를 이용하여 의존하는 객체를 전달할 수 있다.
위 코드는 WriteArticleServiceImpl클래스의 생성자에 식별 값이 "articleDao"인 빈 객체를 전달한다는 것을 의미한다.
코드로는....
OracleArticleDao articleDao = new OracleArticleDao();
WriteArticleServiceImpl writeArticleService = new WriteArticleServiceImpl(articleDao);

ref bean을 안쓰고 직접 constructor-arg ref="articleDao" 도 가능하다. 또한 <value>값도 설정할 수 있는데...
<constructor-arg>
        <value>10</value>
</constructor-arg>

이런식으로 가능핟. value값은 String타입으로 처리된다. 따라서 숫자 3000의 value를 전달해도 파라미터가 String타입의 파라미터가 정의되어있으면 매핑되고,, 만약 스트링이 없고 int타입이 있으면 int타입으로 매핑된다.

프로퍼티

프로퍼티는 익숙하지... setXXXXX()형태의 메소드를 매핑한다. 앞의 set을 빼고 XXXXX가 이름이 된다.
이렇게 생각하자... 
bean은 객체
property는 (set)메소드.. 


<bean name = "monitor" class = "kame.spring.chap02.SystemMonitor" >
    <property name = "periodTime" value = "10" />
    <property name = "sender" value = "smsSender" />
</bean>

setPeriodTime메소드에 파라미터값으로 10을 전달, setSender메소드에 smsSender값을 전달한다. 쉽지 않은가..ㅋ
이외에도 컬렉션타입(set,map,list,제네릭)으로도 의존관계 설정이 가능하니 책을 참조하자.

의존관계 자동 설정

byName : 프로퍼티의 이름과 같은 이름을 갖는 빈 객체를 설정한다.
byType : 프로퍼티의 타입과 같은 타입을 갖는 빈 객체를 설정한다.
constructor : 생성자 파라미터 타입과 같은 타입을 갖는 빈 객체를 생성자에 전달한다.
autodetect : 생성자방식을 먼저 적용하고 byType방식을 적용하여 의존객체 설정한다.


<bean id = "monitor" class = " ....SystemmMonitor" autowire = " byName" />

1)프로퍼티 이름을 이용한 의존 관계 자동 설정
<bean name = "writeArticleService"
         class = "kame.spring.chap02.WriteArticleServiceImpl" 
autowire = "byName" />
<bean name = "articleDao" class = "kame.spring.chap02.MysqlArticlDao" >
<bean name = "myArticleDao" class = "kame.spring.chap02.MysqlArticlDao" >

WriteArticleServiceImpl클래스가 이름이 "articlDao"인 프로퍼티를 갖고 있다면, 이름이 "articleDao"인 빈 객체가 프로퍼티의 값으로 전달된다.

2)타입을 이용한 의존 관계 자동 설정
<bean name = "writeArticleService"
         class = "kame.spring.chap02.WriteArticleServiceImpl"
autowire = "byType" >
<bean name = "myArticleDao" class = "kame.spring.chap02.MysqlArticlDao" >
<bean name = "oracleArticleDao" class = "kame.spring.chap02.OracleArticlDao" >

위코드에서 myArticleDao빈 객체와 oracleArticleDao 빈 객체는 둘 다 ArticleDao 타입이기 때문에 어떤걸 프로퍼티에 넣어야 할 지 결정할 수가 없다. 이럴때 예외를 발생시킨다.

posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:48


최범균님의 책.. 스프링2.5를 보고 공부하고있다.
서평이나 사람들 말을 들어보면 완벽한 책이라고... 베스트셀러에다..
인정한다. 헌데 나랑 좀 맞지 않는 듯... 아..그것보다 내 실력이 쓰레기이기 때문이겠지...ㅋㅋ
구성은 좋은데 너무 딱딱하여 이해가 잘 가지 않는다. 논문보는듯..;;

아무튼 AOP.. 부분.. 다 훑어봤지만 20%정도 이해한듯 하다. 헐..어려워..

AOP
어플리케이션 전반에 걸쳐 필요한 기능. 핵심 비즈니스 기능과 구분하기 위해 공통기능을 공통관심사항(cross-cutting concern)
핵심 로직을 핵심관심사항(core concern)이라고 한다.

AOP용어
Advice : 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의하고 있다. 예를 들어, 메소드를 호출하기 전에 트랜잭션을 시작한다(공통기능) 기능을 적용한다는 것을 정의하고 있다.
Joinpoint :  Advice를 적용 가능한 지점을 의미한다. 메소드호출, 필드값 변경 등이 해당된다.
Pointcut : Joinpoint의 부분 집합으로써 실제로 Advice가 적용되는 Joinpoint를 나타낸다. 스프링에서는 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수 있다.
Weaving : Advice를 핵심 로직 코드에 적용하는 것을 위빙이라 한다. 공통코드를 핵심 로직 코드에 삽입하는 것이 위빙이다.!
Aspect : 여러 객체에 공통으로 적용되는 공통 관심 사항을 Aspect라고 한다. 트랜잭션이나 보안 등이 Aspect의 좋은 예이다.

스프링 API를 이용한 AOP
(1)MethodBeforeAdvice
대상 객체의 메소드를 실행하기 전에 공통 기능을 적용하고 싶을때에 사용되는 Advice인터페이스.

void before(Method method, Object[] args, Object target) throws Throwable;

Method method : 대상 객체에서 실제로 호출될 메소드를 나타내는 Method객체
Object[] args : 메소드 호출시 전달된 인자 목록
Object target : 실제 대상 객체

이외에..
(2)AfterReturningAdvice : 대상객체의 메소드를 실행한 후 공통기능 적용.
(3)ThrowsAdvice : 예외가 발생했을때 공통기능을 적용하고 싶을 때 사용.
(4)MethodInterceptor : 앞의 어드바이스를 모두 합쳐 놓은 인터페이스


Pointcut 및 Advisor 설정
Advice를 작성했다면,, Advice를 어떤 Joinpoint에 적용할지를 지정할 차례이다. 즉, Pointcut을 설정할 차례.

org.springframework.aop.support.JdkRegexMethodPointcut : 정규표현식을 이용하여 포인트컷 정의.
org.springframework.aop.aspectj.AspectJExpressionPointcut : aspectj의 표현식을 이용하여 포인트컷 정의

<bean id = "beforeLogAdvice" class = "kame.......MethodBeforeLogAdvice" />
<bean id = "writePointcut" class = "org.springframework.aop.support.JdkRegexpMethodPointcut">
     <property name = "pattern" value = ".*write.*" />
</bean>

<bean id = "writeAdvisor" class = "org.....DefaultPointcutAdvisor">
    <property name = "advice" ref = "beforeLogAdvice" />
    <property name = "pointcut" ref = "writePointcut" />
</bean>

위 설정은 writeAdvisor는 beforeLogAdvice 어드바이스가 writePointcut 포인트컷에 적용된다는 것을 정의하고 있다. 즉, 메소드 이름에 write를 포함하고 있는 메소드를 호출할때 beforeLogAdvice를 적용하라고 설정하였다.
위 작업은 꾀 성가신 작업인데 RegexMethodPointcutAdvisor를 이용해 작업을 줄일수 있다.

<bean id = "beforeLogAdvice" class = "kame.......MethodBeforeLogAdvice" />

<bean id = "writeAdvisor" class = "org.....RegexMethodPointcutAdvisor">
    <property name = "advice" ref = "beforeLogAdvice" />
    <property name = "pattern" ref = ".*write.*" />
</bean>


AspectJExpressionPointcut

expression프로퍼티를 이용하여 Pointcut을 정의하는 표현식을 설정한다.
<bean id = "getPoint" class = "org......AspectJExpressionPointcut">
      <property name = "expression" value = "execution(public !void get*(..))" />
</bean>

<bean id = "getAdvisor" class = "org.....DefaultPointcutAdvisor" >
       <property name = "advice" ref ="cacheadvice" />
       <property name = "pointcut" ref = "getPoint" />
</bean>
expression프로퍼티는 포인트컷을 표현하는 표현식을 값으로 갖는다. 위 코드에서 excution 명시자는 메소드의 실행을 명시하며, 접근제어가 public 이고 리턴타입이 void가 아니며 메소드의 이름은 get으로 시작하고 0개 이상의 파라미터를 갖는 메소드의 실행 시점을 Pointcut으로 설정함을 의미한다.
posted by 나는너의힘
:
JAVA 2009. 5. 6. 11:34


jdbc 방식의 연결시에는 초기 지연시간 발생하기 때문에 서비스 시간이 지연 → 서비스 시간 개선 → connection을 DB에 미리 연동해두고 필요한 클라이언트에게 연결된 connection을 제공 → 메모리 부하

JNDI(Java Naming & Directory Interface) : JVM → CP
DBCP를 찾아 가기 위한 객체
Context ct = new InitialContext();
DataSource ds = (DataSorce)ct.lookup("java:comp/env/jdbc/등록한 이름");
Connection con = ds.getConnection();

이후는 JDBC와 동일하다.

* DBCP설정
http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html

0. Drivers for older Oracle versions may be distributed as *.zip files rather than *.jar files. Tomcat will only use *.jar files installed in $CATALINA_HOME/common/lib. Therefore classes111.zip or classes12.zip will need to be renamed with a .jar extension. Since jarfiles are zipfiles, there is no need to unzip and jar these files - a simple rename will suffice

1.context configuration
server.xml의 context부분에 추가해준다.

<Resource name="jdbc/myoracle" -- context의 lookup에서 찾아갈 이름, myoracle만 변경가능, 대소문자 주의
              auth="Container"
              type="javax.sql.DataSource"
              driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
              username="scott" 
              password="tiger"
              maxActive="50" -- 확장 커넥션의 생성 갯수, 기본과 동일하거나 기본+10
              maxIdle="40" -- 기본 커넥션의 생성 갯수
              maxWait="-1" -- 대기시간
/>

2. web.xml configuration
일반 클래스(DAO)에서 connection pool을 쓰려면 servlet이나 JSP에서 클래스를 인스턴스화 해서 쓴다.
안되면 web.xml설정, DTD의 설정에 따라 파일에 넣는다.
webcontent → WEB-INF → lib → web.xml
위에서 설정한 resource name으로 변경해준다

<resource-ref>
<description>Oracle Datasource example</description>
<res-ref-name>jdbc/myoracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:30


XML네임스페이스 영문 페이지
http://www.w3.org/TR/REC-xml-names/

spring에서...
의존 관계를 설정하는 방법 중의 하나로...
<property>태그를 사용하지 않고 property 값을 설정하려 할 때 XML네임스페이스를 이용한다.

[XML네임스페이스]

xml네임스페이스는 xml문서에 URI레퍼런스로 구별되는 네임스페이스를 사용하여 xml문서에 쓰인 요소와 속성의 이름을 한정시킬 수 있게 한다.
.....
확장된 이름은 네임스페이스의 이름과 로컬 이름으로 구성된다. URI레퍼런스에서 빈 문자열은 네임스페이스의 이름으로 사용할 수 없다. 동일한 문서의 레퍼런스를 포함하고 있는 상대URI레퍼런스는 네임스페이스 선언에서 사용할 수 없다.
.....
네임스페이스는(정확히 말하자면 네임스페이스 바인딩) 예약된 속성어를 사용하여 선언하며 속성의 이름은 xmlns이거나 xmlns로 시작되어야 한다. XML의 다른 속성과 마찬가지로 여기에서 쓰이는 속성도 직접 입력하거나 디폴트로 해서 생성된다.
속성의 표준값은 URI레퍼런스 - 네임스페이스에 구별되는 네임스페이스의 이름 - 이거나 디폴트이어야 하며 지정된 용도에 맞게 쓰려면 네임스페이스의 이름은 유일성과 영속성을 가지고 있어야 한다. (스키마가 있더라도)이것은 스키마 검색을 위한 직접적인 용도는 아니다.
.....
속성이름이 PrefixedAttName과 일치하면 NCname은, 선언에 나온 요소의 영역에 있는 속성값에서 네임스페이스 이름과 함께 쓰이는 요소와 속성 이름에 결합하여 쓸 수 있는 네임스페이스 접두어를 사용한다. 이 때, 네임스페이스 속성은 공백이 될 수 없다. 
속성이름이 DefaultAttName과 일치하면 속성값에서 네임스페이스 이름은 선언에 나온 요소의 영역에서 디폴트네임스페이스이다.

네임스페이스 이름 http://ecommerce.example.org/schema 에 네임스페이스 접두어 edi가 결합된 네임스페이스 선언의 예

<x xmlns:edi='http://ecommerce.example.org/schema'>
  <!-- the "edi" prefix is bound to http://ecommerce.example.org/schema
       for the "x" element and contents -->
</x>

.....
PrefixedAttName = xmlns : NCname
DefaultAttName = xmlns
prefix = NCname
.....
qualified name은 네임스페이스의 설명을 일컫는다.
접두어는 qualified name의 네임스페이스 접두어 부분을 제공하며 네임스페이스 선언에서 URI레퍼런스와 결합하여 쓰인다.

(...이상 발해석이었음)

즉, 네임스페이스에서 접두어로 사용하는 문자는 NCname이다...(나의 결론)
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:30


1. 클라이언트의 요청을 받을 DispatcherServlet을 web.xml 파일에 설정한다.
2. HandlerMapping을 이용하여 요청 URL과 컨트롤러의 매핑 방식을 설정한다.
3. 클라이언트의 요청을 처리(로직을 수행)할 컨트롤러를 작성한다.
4. 컨트롤러의 처리 결과 응답 화면을 생성할지를 결정하는 뷰 리졸버를 구성한다.
5. 사용자에게 보여주는 JSP를 작성한다.

최소한의 작업.

1. 클라이언트에서 DispatcherServlet에 전달
2. HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체 매핑
3. handleRequest() 메서드를 호출하여 클라이언트의 요청 전달,
    컨트롤러의 handleRequest() 메서드는 처리 결과를 가진 ModelAndView객체 리턴
4. ViewResolver로부터 응답 결과를 생성할 뷰 객체 설정
5. 클라이언트에 전송할 응답 생성
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:15

AOP설정 엘리먼트 (스프링 인 액션 참고)
 AOP 설정 엘리먼트 목적 
 <aop:advisor>  AOP 어드바이저를 정의 한다 
 <aop:after>  After어드바이스를 정의한다.(이 어드바이스는 메서드의 예외발생 여부와 관계 없다.) 
 <aop:after-returning>  After-returning 어드바이스를 정의한다. 
 <aop:after-throwing>  After-throwing 어드바이스를 정의한다. 
 <aop:around>  Around 어드바이스를 정의한다. 
 <aop:aspect>  애스펙트를 정의한다. 
 <aop:before>  Before 어드바이스를 정의한다. 
 <aop:config>  최상위 AOP엘리번트. 대부분의 <aop:*> 엘리먼트는 이 <aop:config>안에 포함되야 한다. 
 <aop:pointcut>  포인트컷을 정의한다. 


스프링 AOP 설정 엘리먼트를 이용 예

<?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"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 

    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

         http://www.springframework.org/schema/aop 

         http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">



    <bean id="audience" class="chapter4.springidol.Audience" />

    

    <aop:config>

    

      <aop:aspect ref="audience">

      

        <aop:before

          method="takeSeats"

          pointcut="execution(* *.perform(..))" />


        <aop:before

          method="turnOffCellPhones"

          pointcut="execution(* *.perform(..))" />

          

        <aop:after-returning

          method="applaud"

          pointcut="execution(* *.perform(..))" />

          

        <aop:after-throwing

          method="demandRefund"

          pointcut="execution(* *.perform(..))" />

          

      </aop:aspect>

      

    </aop:config>

</beans>


대부분의 스프링 AOP설정 엘리먼트는 <aop:config>엘리먼트 내에 사용됩니다. 이 안에는 하나 이상의 어드바이저, 애스펙트, 포인트컷을 선언할 수 있습니다. 

 헌데 여기서 중복된 코드를 많이 볼수있습니다. 각 어드바이스의 pointcut 애트리뷰트들이 같은 값을 가지고 있는데요. 이는 DRY(don't repeat yourself)의 원칙 위반입니다; 이래서~ 바꾸는 방법은 밑에 소스에서 처럼 <aop:aspect>안에 <aop:pointcut> 엘리먼트를 이용해서 포인트컷에 이름을 부여하고 이를 다른 어드바이스에서 참조하는 방법입니다.

       ...

    <aop:config>

    

      <aop:aspect ref="audience">

        <aop:pointcut 

          id="performance"

          expression="execution(* *.perform(..))" />

      

        <aop:before

          method="takeSeats"

          pointcut-ref="performance" />


        <aop:before

          method="turnOffCellPhones"

          pointcut-ref="performance" />

          

        <aop:after-returning

          method="applaud"

          pointcut-ref="performance" />

          

        <aop:after-throwing

          method="demandRefund"

          pointcut-ref="performance" />

      </aop:aspect>

      

    </aop:config>

    ...


<aop:pointcut>은 같은 <aop:aspect>내부의 모든 어드바이스가 참조할 수있는 포인트컷으로 정의를 하였는데, 
이 <aop:pointcut>을 <aop:config>의 바로 하위에 정의하게 되면 다른 애스펙트에서도 이 포인트 컷을 참조할 수가 있습니다.

posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:14

@Aspect 어노테이션은 AspectJ 5버전에 새롭게 추가된 어노테이션으로, @Aspect 어노테이션을 사용하면 설정파일에 Advice 및 Pointcut등의 설정을 하지 않고도 자동으로 Advice를 적용 할 수 있습니다. 스프링2부터 이 어노테이션을 지원하고 있으며 설정파일에 <aop:aspectj-autoproxy> 태그를 설정파일에 추가해주면 @Aspect 어노테이션이 적용된 빈을 Aspect로 사용할 수 있게 됩니다. aop네임스페이스도 설정파일에 포함시켜야 합니다.

스프링인 액션 참고 자료.
설정파일

<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"

     xsi:schemaLocation="http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

       http://www.springframework.org/schema/aop 

      http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">



  <aop:aspectj-autoproxy />

  <bean class="chapter4.springidol.Audience" />

  ....


</beans>



어노테이션이 적용된 자바소스파일

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;


@Aspect

public class Audience {

public Audience() {

}


@Pointcut("execution(* *.perform(..))")

public void performance() {

}


@Before("performance()")

public void takeSeats() {

System.out.println("The audience is taking their seats.");

}


@Before("performance()")

public void turnOffCellPhones() {

System.out.println("The audience is turning off their cellphones");

}


@AfterReturning("performance()")

public void applaud() {

System.out.println("CLAP CLAP CLAP CLAP CLAP");

}


@AfterThrowing("performance()")

public void demandRefund() {

System.out.println("Boo! We want our money back!");

}

}



@Around어노테이션 사용시 주의점

@Around어노테이션 사용시에는 반드시 proceed()를 호출하는 부분이 들어가야 합니다. proceed()가 호출이되어야 원래 호출되야 할 메서드로 실행이 넘어갑니다. 이를위해 Around어드바이스가 적용된 메소드에서 ProceedingJoinPoint객체를 인자로 받도록 선언을 해 주어야 합니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:13

Advice 유형별 인터페이스
 어드바이스 유형 인터페이스 
 Before  org.springframework.aop.MethodBeforAdvice
 After-returning  org.springframework.aop.AfterReturningAdvice
 After-throwing  org.springframework.aop.ThrowAdvice
 Around  org.aopalliance.intercept.MethodInterceptor
 Introduction  org.springframework.aop.IntroductionInterceptor 

Before Advice
target의 특정 메소드를 실행하기 전에 어떠한 일을 추가하고 싶을 경우에 사용합니다.

After-retuning Advice
target객체의 특정 메소드의 실행을 무사히 완료한 뒤에 추가할 작업을 정의 할 때 사용합니다. (예외가 발생하지 않았을 경우)

After-throwing Advice
Advice 가 적용이 되는 메소드에서 예외(Exception)가 발생했을 경우 특정한 일을 추가하고자 할 때 사용합니다.

Around Advice
위에서 살펴본 Before, After-returning, After-throwing 어드바이스의 역할을 모두 다 할 수 있는  강력한 Advice입니다. 또 대상이 되는 메소드의 실행 여부도 결정할 수 있으며, target 메소드의 반환 값을 변경할 수 도 있습니다.

Introduction Advice
위의 어드바이스들과는 다른 매우 특이한 어드바이스로 target객체 자체에 별도의 메소드 또는 속성을 추가합니다.


Classic AOP
MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice 예제 (Spring In Action 참고)

/**

 * 세가지 어드바이스 유형을 구한다. MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice

 *

 */

public class AudienceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

public AudienceAdvice() {

}


// 메소드 실행전에 호출된다.

public void before(Method method, Object[] args, Object target) throws Throwable {

audience.takeSeats();

audience.turnOffCellPhones();

}


// 성공적으로 메소드가 반환되면 실행된다

public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {

audience.applaud();

}


// 예외가 발생되면 실행된다.

public void afterThrowing(Throwable throwable) {

audience.demandRefund();

}


private Audience audience;


public void setAudience(Audience audience) {

this.audience = audience;

}

}



  <bean id="audience" class="chapter4.classicSpringAop.Audience" />


  <bean id="audienceAdvice"

class="chapter4.classicSpringAop.AudienceAdvice">

    <property name="audience" ref="audience" />

  </bean>

  

  <bean id="audienceAdvisor"

        class="org.springframework.aop.support.DefaultPointcutAdvisor">

    <property name="advice" ref="audienceAdvice" />

    <property name="pointcut" ref="performancePointcut" />

  </bean>


  <bean id="performancePointcut"

class="org.springframework.aop.aspectj.AspectJExpressionPointcut">

    <property name="expression" value="execution(* perform(..))" />

  </bean>


먼저 맨 밑의 포인트컷 정의 부분을 보면 AspectJExpressionPointcut을 사용하고 있는데 이는 AspectJ 스타일의 표현식을 이용한 것입니다. 

여기서 AspectJ의 표현식을 알아보면

JdkRegexpMethodPointcut(정규표현식)을 이용한다면

  <bean id="performancePointcut"

class="org.springframework.aop.aspectj.JdkRegexpMethodPointcut">

    <property name="pattern" value="*.perform" />

  </bean>

이렇게 쓸 수 있습니다. 

정규표현식을 알아본다면
 기호 의미 
 . 어떤 문자든 딱 한 글자
 *  * 앞에 있는 문자가 여러개 있을 수 있음
 +  + 앞에 있는 문자가 최소한 한 개에서 여러개 있을 수 있음 
 \  \ 뒤에 오는 문자가 있어야한다


DefaultPointcutAdvisor는 단순히 어드바이스(audienceAdvice 참조)와 포인트컷(performancePointcut)을 결합시키는 어드바이저 클래스입니다.

포인트컷과 어드바이스를 동시에 정의할수있는 어드바이저 클래스도 있는데 RegxpMethodPointcutAdvisior입니다.
RegxpMethodPointcutAdvisior를 이용한다면

   <bean id="audienceAdvisor"

        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

     <property name="advice" ref="audienceAdvice" />

     <property name="pattern" value=".*perform" />

   </bean>

이렇게 쓰고 기존의 포인트컷 부분은 없애 주시면 됩니다.


ProxyFactoryBean 활용

    <bean id="dukeTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <bean id="duke" class="org.springframework.aop.framework.ProxyFactoryBean">

      <property name="target" ref="dukeTarget" />

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterfaces" value="chapter2.springidol.Performer" />

    </bean>

    

    <bean id="stevieTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <!-- 똑같은 코드의 중복 -->

    <bean id="stevie" class="org.springframework.aop.framework.ProxyFactoryBean">

      <property name="target" ref="stevieTarget" />

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterfaces" value="chapter2.springidol.Performer" />

    </bean>


duke 프록시와 stevie 프록시가 같은 코드가 중복이 된다. 다른 빈들을 만들때도 이런식으로 하면 반복되는 정보가 너무 많아진다. 이럴 때는 추상 빈으로 ProxyFactoryBean을 하나 선언해 두고, 이를 부모삼아 각 프록시 빈에서 재사용 하면 된다.

변경후~~

    <bean id="dukeTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>


    <bean id="stevieTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <bean id="audienceProxyBase" 

      class="org.springframework.aop.framework.ProxyFactoryBean"

      abstract="true">

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterface" value="chapter2.springidol.Performer" />

    </bean>

    

    <bean id="stevie" parent="audienceProxyBase">

      <property name="target" ref="stevieTarget" />

    </bean>

    

    <bean id="duke" parent="audienceProxyBase">

      <property name="target" ref="dukeTarget" />

    </bean>



ProxyFactoryBean말고 autoproxing을 사용하자.

위에 작성했던 proxy가 들어가기 전의 코드로 돌아가서~ 프록시땜시 뒤에 붙혀주었던 xxxTarget 은 전부다 원래 빈의 이름으로 바꿔줍시다. 그리고 밑에 요거만 붙혀놓으면... 오토프록시가 설정이되어 할일이 없어집니다... 

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />


DefaultAdvisorAutoProxyCreator 클래스는 빈으로 등록만 되면, 자동으로 모든 어드바이저의 포인트컷이 특정 빈의 메서드에 일치하는지 확인하고, 일치하는 빈을 찾으면해당 어드바이스가 적용된 프록시로 대체해 놓습니다. 한마디로, 어드바이저가 일치하는 빈은 모두 자동으로 프록시화 됩니다.

이 방법들 말고 더욱 간단하게 설정하는 방법은 다음으로 미룹니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:12

Aspect Oriented Programming의 약자로 여러 곳에 흩어져 존재할 수 밖에 없었던 코드를 모듈화 할 수있는 프로그래밍 기법입니다. Aspect라는 것을 사용하요 츠로그래밍을 할 때 특정한 관심사를 가진 코드 부분을 별도의 모듈로 분리함으로써, 기존 객체지향의 강력한 기능(상속, 위임)만으로는 처치가 곤란했던 중복을 제거 할 수 있게 되었습니다.
로깅, 트랜잭션 처리, 모니터링 관련 코드들을 AOP를 적용하여 하나의 Aspect로 모듈화각 가능하므로 서비스계층이나 도메인 계층에서 관련된 코드들의 제거 할수 있습니다. 또 특정 클래스에 종속성을 가지던 현상을 제거 할수 있게 되었습니다.

Spring AOP용어의 정리

Advice : 언제 무엇을 할지 나타냅니다. 즉 애스펙트가 해야하는 작업언제 그 작업을 수행해야 하는지를 정의한 것이 어드바이스 입니다. (실제로 Target 객체에 적용할 일을 나타냄.)

◎ Joinpoint : Advice를 적용할 시점을 말합니다. (생성자 호출, 필드에 접근, 필드의 값 변셩, 메소드 호출등의 시점.) Spring AOP는 메소드 호출 Joinpoint만 지원합니다.

Pointcut : Joinpoint의 부분집합으로 애스펙트가 어드바이스 할 조인포인트의 영역을 좁히는 일을합니다.

Advisor : 하나의 Advice와 하나의 Piontcut을 묶은 것. Aspect는 여러개의 Advice와 Pointcut을 가지고 있는 것을 말합니다. 즉 Advisor도 하나의 Advice와 Pointcut을 가지고 있는 Aspect라고 할 수 있습니다.

Aspect : Advice + Pointcut 
어드바이스와 포인트컷을 합친 것이 애스펙트 입니다. 두가지 정보가 합쳐지면 애스팩트가 무엇을 언제해야할지, 즉 애스펙트에 필요한 모든 정보가 정의됩니다.

Introduction : 기존 클래스의 코드 변경 없이도 새 메소드나 멤버변수를 추가하는 기능입니다.

Target : Advice의 대상이 되는 객체를 말합니다.

Proxy : 프록시 객체
Spring AOP는 Proxy객체를 사용합니다. 프록시는 어드바이스를 타깃 객체에 적용하면 생성되는 객체입니다.

Weaving : Target 객체에 Aspect를 적용하는 과정.
타깃 객체에 애스펙트를 적용해서 새로운 프록시 객체를 생성하는 절차를 위빙이라고 합니다. 애스펙트는 타깃 객체의 조인포인트로 위빙됩니다. 
위빙은 대상 객체의 생애중 컴파일 시점, 런타임 시점, 클래스 로딩 시점에 할 수 있는데, Spring AOP는 런타임시에 동시적으로 Proxy객체를 생성합니다.


Spring AOP의 특징

◎ 자바로 작성한다.

◎ 스프링 애스팩트는 실행시간에 만들어진다. (런타임시에 특정 Target객체의 Proxy객체를 만들어 Aspect로 사용한다.) 
스프링에서 Proxy를 만드는 방법은 두가지가 있는데 인터페이스 기반으로 Proxy를 만드는 방법과 클래스를 기반으로 Proxy를 만드는 방법이 있습니다. 인터페이스를 기반으로 Proxy를 만들때는 JDK의 Proxy클래스를 사용하기 때문에, 별도의 라이브러리를 클래스 패스에 추가할 필요가 없으며, 인터페이스 기반의 코딩으로 보다 유연한 코드 작성이 가능합니다. 반면 클래스 기반 Proxy를 만들 때는 CGLIB 라이브러리를 필요로 하며, 상속을 사용하여 만들 수 없기 때문에 final로 선언된 메소드를 가진 클래스의 Proxy객체를 생성할 수 없습니다.

method joinpoint만 지원한다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:12

이전 글에 이어서 의존관계자동설정에 대해서 알아 보겠습니다.
스프링은 의존하는 빈 객체의 타입이나 이름을 이용하여 의존 객체를 자동으로 설정할 수 있습니다. 여기(The Spring Framework - Reference Documentation)에 자세한 내용이 있네요 ^^;

일단 네가지 방식이 존재합니다. 방식으로는
1. byName : 프로퍼티의 이름과 같은 이름을 갖는 빈객체를 설정
2. byType : 프로퍼티의 타입과 같은 타입을 갖는 빈객체를 설정
3. constructor : 생성자 파라미터 타입과 같은 타입을 갖는 빈객체를 설정
4. autodetect : constructor방식을 먼저 적용, byType방식을 적용
네 가지 방식이 있습니다.

일단 설정파일에 포함된 모든 빈 객체에 대해서 특정방시의 자동 설정을 적용하고 싶다면
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:p="http://www.springframework.org/schema/p"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans      
  5.   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  6.   default-autowire="byName">  
  7. ...    
  8. ...   
  9. </beans>  
이렇게 해주시면 됩니다.

네가지의 설정 중에서 예를 하나만 들겠습니다.

  1. <bean name="userService" class="yoyojyv.service.UserServiceImpl" autowire="byName"/>  
autowire의 속성 값을 네가지 속성중에 하나만 주면 됩니다. 여기선 byName을 썼군요.
DI설정을 프로퍼티 방식(setter Injection)을 썼을경우에 autowire속성을 constructor로 하면 어떻게 될까요? 직접 해본 결과 오류가 납니다. ㅋㅋ 각 설정에 맞게 써 주어야 하고, 또 byType, constructor, autodetect의 경우 동일한 타입의 빈 객체를 2개 이상 정의를 하게되면 오류가 납니다. 지가 어떤빈을 써먹어야 할지 결정을 못하네요~

의존 관계를 자동으로 알맞게 설정해주는 기능은 설정파일의 크기를 줄여주고 유용한 기능이긴 하지만, 설정파일만으로 빈 객체간의 의존관계를 파악하기 힘들다는 단점이 있습니다. 규모가 커질수록~ 더 파악하기 힘들어지기때문에 상황에 맞게~ 되도록이면 설정파일에 의존관계를 명시하는 것이 좋은 방법이라고 합니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:10

스프링 프레임워크가 가지는 가장 핵심적인 기능은 IOC(Inversion Of Control)입니다. 그중에서 DI(Dependency Injection)는 스프링 프레임워크에서 지원하는 IOC의 한 형태입니다.
DI는 클래스 사이의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동적으로 연결해 주는 것을 말합니다. 컨테이너가 의존관계를 자동적으로 연결시켜 주기때문에 컨테이너 API에 종속되는 것을 줄일 수 있습니다.

의존관계를 설정하는 방식으로는 자주 쓰이는 것들에는 생성자 방식(Constructor Injection), 프로퍼티 설정 방식(Setter Injection) 등이 있습니다.

1. 생성자 방식
UserServiceImpl.java 

public class UserServiceImpl implements UserService {

  private UserDAO userDAO;

  public UserServiceImpl(UserDAO newUserDAO) {

    this.userDAO = newUserDAO;

  }


  ...


}



applicationContext.xml

  <bean id="userDAO" class="yoyojyv.dao.MySQLUserDAO"/>

  <bean id="userService" class="yoyojyv.service.UserServiceImpl">

    <constructor-arg>

      <ref bean="userDAO"/>   

    </constructor-arg>

  </bean>


UserServiceImpl.java 의 생성자와 applicationContext.xml 의 3~5번째줄의 <constructor-arg>태그를 이용하여  의존하는 객체를 전달 할 수 있습니다. 

    <constructor-arg ref="userDAO"/ >

바로위에 처럼
한줄로 표현도 가능하죠.


2. 프로퍼티 설정 방식
UserServiceImpl.java 

public class UserServiceImpl implements UserService { 

  private UserDAO userDAO;    

  public void setUseDAO(UserDAO newUserDAO) {   

    this.userDAO = newUserDAO;  

  } 

  ....

 }


applicationContext.xml

  <bean id="userDAO" class="yoyojyv.dao.MySQLUserDAO"/>

  <bean id="userService" class="yoyojyv.service.UserServiceImpl">

    <property name="userDAO">

      <ref bean="userDAO"/>

    </property>

  </bean>


UserServiceImpl.java 의 3~5번째줄의 setter메소드와 applicationContext.xml 의 3~5번째줄의 <property>태그를 이용하여  의존하는 객체를 전달 할 수 있습니다. 

나머지 방식들과 IoC container에관한 내용은 여기(The Spring Framework - Reference Documentation)<-- 에서 확인 하세요~
posted by 나는너의힘
:
JAVA 2008. 8. 24. 21:59

[스윙] JEditorPane에서 html 을 표현하도록 해주는 방법

contentType 을 text/html 로 해준다.

제목: [스윙] JTable 에서 row 단위로 색깔을 다르게 주고 싶을때

JTable 생성시 prepareRenderer 메소드를 다음과 같이 재정의 해준다.

JTable table = new JTable() {
             public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                 Component c = super.prepareRenderer(renderer, row, column);
                 if (!isCellSelected(row, column)) {
                     if (row % 2 == 0) {
                        c.setBackground(Color.blue);
                     } else {
                        c.setBackground(Color.red);                        
                     }
                 }
                 
               return c;
             }
         };

제목: [스윙]SwingUtilities.invokeLater 와 SwingUtilities.invokeAndWait 의 차이점

SwingUtilities.invokeLater 와 SwingUtilities.invokeAndWait 메소드는 외부에서 다이얼로그와 같은 창을
띄울때 다이얼로그에 포커스가 가도록 해주는 함수들이다.

그런데 위의 두함수의 차이점은 invokeLater의 경우 호출한쪽에서 제어권을 가지지 않는경우이다 즉 비동기화를 의미하며 invokeAndWait 는 그 반대가 된다.



제목: [스윙] JLabel 에서 background 에 색깔을 주려면

opaque 를 true 로 해줘야 색깔이 바뀐다

제목: [스윙] JTable의 데이타가 변했는데도 화면에 변화가 생기지 않을때

JTable내의 데이타모델을 불러와서 다음과같이 2개를 메소드를 호출해준다.
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
dtm.fireTableStructureChanged();
dtm.fireTableDataChanged();

 

제목: [스윙] JOptionPane 이 스레드에 의해서 호출이 될때 제대로 동작하지 않을때

JOptionPane은 자신의 부모창이 아닌 외부 스레드에 의해서 호출이 될때 버튼이 활성화되지 않는 문제점이 있다. 이때 다음과 같이 해주면 된다
SwingUtilities.invokeAndWait(new Runnable()              {                
public void run() { JOptionPane.showXXXX...};              
});

 

 

제목: [스윙] DefaultTableModel 을 사용하면서 CheckBox모양이 나타나지 않을때

다음과 같이 재정의해주면 됩니다.
    public Class getColumnClass(int c) {
       return getValueAt(0, c).getClass();
    }

 

 

제목: [스윙] JComboBox 에서 아이템이 변할때 한번만 이벤트를 먹도록 하는 방법

if(e.getStateChange() == e.SELECTED){
}

public void itemStateChanged(java.awt.event.ItemEvent e) {      
   if(e.getStateChange() == e.SELECTED){
   }
}

posted by 나는너의힘
:
JAVA 2008. 8. 19. 10:35

FocusListener 구현 및 실행단계
  1. Class Name 다음에 implements FocusListener를 선언해 주었다.
  2. 아래와 같은2개의 메소드를 정의해준다.
  3. public void focusGained(FocusEvent e){}
    public void focusLost(FocusEvent e){}
  4. Focus Event를 발생시켜줄 Component에 addFocusListener(this);을달아준다.
  5. 예)ui.jLabel2.addFocusListener(this);
  6. 포커스를 점유할때 발생하는 Event처리는 focusGained, 포커스가 떠날때 발생하는 Event처리는 focusLost메소드에 각각 정의해 준다.
  7. 아래 예제는 jLabel2에 포커스가 왔을대 sumSu(iCount); 메소드를 호출하는 로직을 구현한것이다.

  public void focusGained(FocusEvent e){
    int iCount = 0;
    //Event를 발생시킨 Component를 찾아 getEvent에 담는다.
    Object getEvent = e.getSource();
    //getEvent와 ActionEvent가 발생할수 있는 Component를 비교하여 Event를 발생시킨 Component를 찾아내고
    //Action 처리를 해준다.
    if(getEvent.equals(ui.jLabel2)) {
      iCount = Integer.parseInt(ui.jTextField1.getText());
      sumSu(iCount);
    }
  }

  private void addEvent() {
    ui.jLabel2.addFocusListener(this);
}
어디서 퍼왔는지는 가물 가물

개인 학습용이니 너무 욕하지는 마세요~

posted by 나는너의힘
:
JAVA 2008. 8. 15. 17:11

class OutDate
{
 public static void main(String[] args)
 {
 java.util.Date setValue = new java.util.Date();
 String strSetValue;
 System.out.println("[Date -> String]");
 java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   
 java.text.SimpleDateFormat ymd = new java.text.SimpleDateFormat("yyyy-MM-dd");   
 strSetValue = sdf.format(setValue);
 System.out.println(strSetValue);
 strSetValue = ymd.format(setValue);
 System.out.println(strSetValue);
 }
}
/*
[Date -> String]


Date setValue = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   
strSetValue = sdf.format(setValue);
 

[String-> Date]


String value = "2008-01-30";

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date tmp = df.parse(value);


[어제 날짜 얻기]

Calendar calendar1 = new GregorianCalendar();
calendar1.add(Calendar.DATE, -1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   
String defaultStartRegDate = sdf.format(calendar1.getTime());

*/

posted by 나는너의힘
: