2017-03-13 3 views
0

메소드 레벨 유효성 검증을 올바르게 수행 할 수 없습니다. 아니면 어떻게 작동하는지 이해할 수 없습니다.bean 메소드의 SpringBoot 검증 매개 변수와 리턴

내 응용 프로그램 클래스는 아래와 같습니다. 아주 간단합니다. 빈 정의가 MethodValidationPostProcessor입니다. 또한 Greeter 서비스를 실행합니다.

@SpringBootApplication 
public class App implements CommandLineRunner { 
    private final Greeter greeter; 

    public App(Greeter greeter) { 
     this.greeter = greeter; 
    } 

    public static void main(String[] args) { 
     new SpringApplicationBuilder().main(App.class).sources(App.class).web(false).run(args).close(); 
    } 

    @Bean 
    public org.springframework.validation.beanvalidation.MethodValidationPostProcessor methodValidationPostProcessor() { 
     return new MethodValidationPostProcessor(); 
    } 

    @Override 
    public void run(String... args) throws Exception { 
     final Input input = new Input(); 
     input.setName("j"); 
     final String messageFromInput = greeter.getMessageFromInput(input); 

     final String messageFromString = greeter.getMessageFromString("j"); 
    } 
} 

아래의 Greeter service. 여기서 나는 입력과 출력의 유효성을 검증 할 것을 기대한다.

@Service 
@Validated 
public class Greeter { 
    String getMessageFromInput(@Valid @NotNull Input name) { 
     return "[From Input] Greetings! Oh mighty " + name + "!"; 
    } 

    String getMessageFromString(@Size(min = 4) String name) { 
     return "[From String] Greetings! Oh mighty " + name + "!"; 
    } 
} 

입력 DTO도 매우 간단합니다.

public class Input { 
    @NotEmpty 
    @Size(min = 3) 
    private String name; 

    // Getters, setters and toString ommited. 
} 

직접 문자열과 DTO의 이름은이 설정에서 예외가 발생하는 문자 일뿐입니다. 불행히도 아무 일도 일어나지 않고 응용 프로그램이 성공적으로 완료됩니다. 그것은 컨트롤러의 방법으로 작동합니다. 그러나 나는 모든 bean의 메소드를 사용하기를 원한다.

+1

생성자 인수로'Greeter'를 사용하지 마십시오. 이것은 빈의 초기 생성을 유발하여 더 이상 프록시 생성을위한 후보가 아니므로 유효성 검사가 적용되지 않습니다. 'CommandLineRunner'를 생성하고 대신'Greeter'를 메소드 인자로 주입하는'@ Bean' 메소드를 생성하십시오. 또한 AOP는 공개 메소드에서만 작동하므로 메소드를 'public'으로 설정하십시오. –

+0

초기 콩 만들기에 대해 옳습니다. 러너를'Greeter' 인자를 가진 빈 공장 메소드로 옮길 때 잘 동작합니다. Greeter의'public' 메소드 접근은 무의미한 것으로 보입니다. 이제 당신이 그것에 대해 언급 할 때, 나는 Greeter가 프록시 후보자가 아님을 나타내는 로그 파일의 정보를 기억합니다. 이제 저는 그 의미가 무엇인지 압니다. – waste

답변

2

빈을 생성자 인수로 (@Configuration 클래스)으로 주석 된 클래스에 삽입하고 있습니다. 이러한 종속성을 충족시키기 위해 GreeterApplicationContext의 시작 프로세스 초기에 만들어 지므로 프록시 생성 후보로 제거됩니다.

생성자 인수로 삽입하는 대신 CommandLineRunner 논리를 @Bean 주석이 달린 메서드로 이동하고 Greeter을 종속으로 삽입하면됩니다. 이것은 빈의 생성을 지연시킬 것이므로 프록시를 위해 사용 가능하게 만든다.

@Bean 
public CommandLineRunner runner(Greeter greeter) { 
    return new CommandLineRunner() { 

     @Override 
     public void run(String... args) throws Exception { 
      final Input input = new Input(); 
      input.setName("j"); 
      final String messageFromInput = greeter.getMessageFromInput(input); 

      final String messageFromString = greeter.getMessageFromString("j"); 
     } 
    }; 
} 

또 다른 것은

Greeter의 당신의 방법이 있어야 할 것입니다, 프록시의 성격, public 때문에.

관련 문제