2010-12-29 3 views
0

스프링 프레임 워크를 사용하여 Java 1.5에서 개발 한 웹 응용 프로그램이 있습니다. 응용 프로그램에는 일련의 정보가 재 그룹화되고 사용자가 일부 상태를 수정할 수있는 간단한 페이지 인 "대시 보드"가 포함되어 있습니다. 관리자는 세 개의 대시 보드에 대해 데이터베이스에 로깅 시스템을 추가하기를 원합니다. 각 대시 보드에는 정보가 다르지만 로그는 날짜와 사용자의 로그인으로 추적해야합니다.스프링을 사용하여 전략 패턴을 효율적으로 구현하는 방법은 무엇입니까?

interface DashboardLog { 
    void createLog(String login, Date now); 
} 

// Implementation for one dashboard 
class PrintDashboardLog implements DashboardLog { 
    Integer docId; 
    String status; 

    void createLog(String login, Date now){ 
    // Some code 
    } 
} 

class DashboardsManager { 
    DashboardLog logger; 
    String login; 
    Date now; 

    void createLog(){ 
    logger.log(login,now); 
    } 
} 

class UpdateDocAction{ 
    DashboardsManager dbManager; 

    void updateSomeField(){ 
     // Some action 
     // Now it's time to log 
     dbManagers.setLogger = new PrintDashboardLog(docId, status); 
     dbManagers.createLog(); 
    } 
} 

Appcontext.xml : I 따라서 의존성을 사용하지 않는이 솔루션에서

<bean id="dashboardManagers" class="...DashboardManagers" /> 

내가하고 싶은 무엇

이 같은 종류의 전략 패턴을 구현하는 것입니다 주입. 이런 식으로 "올바른"(좋은 연습, 성능, ...)? DI를 사용할 수있는 더 좋은 방법이 있습니까?

참고 : 생성자 및 getter/setter와 같은 기본 사항을 작성하지 않았습니다.

+0

userId 만 전달하고 데이터베이스에서 날짜를 설정하는 것이 좋습니다. 그것은 "프로그래머 schenanigans"의 가능성을 제한합니다. – DwB

답변

1

당신이 가지고있는,하지만 당신은 스프링을 사용하고 있다는 사실을 고려으로는 전략 패턴을 사용하는 완벽 "올바른"하지만 - 그것은 더 나은은 스프링 프레임 워크가 제공하는 Dependency Injection 메커니즘을 사용하는 것입니다 - 수도 프레임 워크가 핵심 강점 중 하나로서 제공해야하는 것을 사용합니다.

+0

그 이유는 내가 전략 패턴이 내 필요와 완벽하게 일치한다고 생각 하긴하지만 그 물건의 정확성에 대해 스스로에게 질문하는 이유입니다. – Anth0

+0

weelll - 선택 여부에 상관없이 '정확성'이 관련된 한 어떤 문제도 보이지 않습니다. Spring의 DI 기능을 사용합니다. 성능이나 논리가 확실하지 않은 경우 접근 방법에 아무런 해가 없습니다. 괜찮아. 적어도 Spring MVC의 기능을 사용하고 있다고 가정하고 있습니다. 그렇지 않으면 Spring을 사용해야하는지 여부를 물어야하기 때문입니다. – anirvan

2

솔루션은 updateSomeField()를 호출 할 때마다 PrintDashboardLog의 새 인스턴스를 만듭니다. 이것은 불필요한 시간/메모리/GC 노력을 소비 할 수 있습니다. 또한 설계 관점에서 각 대시 보드마다 하나의 DashboardLog가 있고 각 호출마다 새로운 대시 보드 로그가없는 것이 좋습니다.

로깅이 모범 사례 중 하나 인 측면을 사용하는 것이 좋습니다. 예 :

<?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.5.xsd 
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 

    <bean id="loggingAspect" class="com.yourcompany.yourapplication.aspects.DashboardLogAspect" /> 

    <aop:aspectj-autoproxy> 
     <aop:include name="loggingAspect" /> 
    </aop:aspectj-autoproxy> 

</beans>  


package com.yourcompany.yourapplication.aspects; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 

@Aspect 
public class DashboardLogAspect { 

    @Around("execution(* com.yourcompany.yourapplication..*Action+.*(..)) && target(target)") 
    public Object logActionCall(ProceedingJoinPoint pjp, Object target) throws Throwable { 

     long before = System.nanoTime(); 

     Object returnValue = pjp.proceed(); 

     long after = System.nanoTime(); 
     long durationNs = after - before; 

     String logMsg = target.getClass() + "." + pjp.getSignature().toShortString() + " (" + durationNs + " ns)"; 

     // TODO: store the log message in your database 
     System.out.println(logMsg); 

     return returnValue; 
    }    
} 

이렇게하면 'Action'으로 끝나는 응용 프로그램 클래스에 대한 모든 호출이 기록됩니다. 또한 각 통화가 완료 될 때까지 걸리는 시간이 추가됩니다. 특정 메서드 이름 패턴에 대한 Around 조언을 조정할 수도 있습니다. the AspectJ programming guide

1

각 "대시 보드"에 컨트롤러가있는 경우 컨트롤러에서 로깅을 호출하지 않는 것이 좋습니다.


public interface DashboardLog 
{ 
    void createLog(...); 
} 

public class DashboardUno 
implements DashboardLog 
{ 
    ... 
    public void createLog(...) 
    { ... } 
} 

@Controller 
@RequestMapping("/blah/schmarr") 
public class BlahController 
{ 
    ... 
    @RequestMapping(value = "/xxx") 
    public String someMeaningfulName(...) 
    { 
     DashboardUno elEsUno; 
     ... get the dashboard object ... 
     elEsUno.createLog(...); 
     ... 
    } 
}
관련 문제