1

Web 環境でSpring Framework4.3.3 を使用しています。

私は、依存関係以外の方法を目的として使用する を介したリクエストに@Controller使用されています。後者は、などを使用しています...WebWeb Browser@ControllerRest@Service

「Rest」を使用した「Web」に関するこのアプローチは、セクションのSpring MVC を使用したコンテンツ ネゴシエーションで説明されていCombining Data and Presentation Formatsます。ここまでは、開発/テストおよび本番環境で正常に動作します。価値のあるアプローチです。

と を使用しているため、クラスRestには と注釈が付けられています。@ControllerResponseEntity<?>@ResponseBody

問題はAOP

私が持っているそのインフラストラクチャについて:

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {

}

sについて、@Controller次の 2 つのクラスがあります。

  • PersonaDeleteOneControllerと:
    • deleteOne(@PathVariable String id, Model model)為に@GetMapping
    • deleteOne(@PathVariable String id, RedirectAttributes redirectAttributes)為に@DeleteMapping
  • PersonaRestController
    • deleteOne(@PathVariable String id)為に@DeleteMapping

これら 2 つのクラスは、次の名前の同じパッケージ内で宣言されています。

  • com.manuel.jordan.controller.persona

私は次のものを持っています@Pointcut

@Pointcut(value=
"execution(* com.manuel.jordan.controller.*.*Controller.deleteOne(String, ..)) 
&& args(id) && target(object)")
public void deleteOnePointcut(String id, Object object){}

これ@Pointcutは、次のアドバイスに使用されます。

@Before(value="ControllerPointcut.deleteOnePointcut(id, object)")
public void beforeAdviceDeleteOne(String id, Object object){
    logger.info("beforeAdviceDeleteOne - @Controller: {} - Method: deleteOne - id: {}", object.getClass().getSimpleName(), id);
}

テストを実行すると、次のパターンが出力されるRestことを確認できます。AOP + logging

  • @Controller(残り) -> @Service->@Repository

ここまでのすべての作業はどのように期待されますか

テストを実行すると、次のパターンが出力されるWebことを確認できます。AOP + logging

  • @Controller(残り) -> @Service->@Repository

私が必要または期待しているのは次のとおりです。

  • @Controller(ウェブ) -> @Controller(レスト) -> @Service->@Repository

何が間違っているか、または不足していますか?. deleteOneシグニチャーは、そのパラメーターについてあいまいではありません。

プロダクションの場合も同じです。

アルファ

ここにコントローラーがあります:

@Controller
@RequestMapping(value="/personas")
public class PersonaDeleteOneController {

    private final PersonaRestController personaRestController;

    @Autowired
    public PersonaDeleteOneController(PersonaRestController personaRestController){
        this.personaRestController = personaRestController;
    }

    @GetMapping(value="/delete/{id}",
                produces=MediaType.TEXT_HTML_VALUE)
    public String deleteOne(@PathVariable String id, Model model){
        model.addAttribute(personaRestController.findOneById(id));
        model.addAttribute("root", "/personas/delete");
        return "persona/deleteOne";
    }

    @DeleteMapping(value="/delete/{id}",
                   produces=MediaType.TEXT_HTML_VALUE)
    public String deleteOne(@PathVariable String id, RedirectAttributes redirectAttributes){
        personaRestController.deleteOne(id);
        redirectAttributes.addFlashAttribute("message", "process.successful");
        return "redirect:/message";
    }

}

@Controller
@RequestMapping(value="/personas")
public class PersonaRestController {

    private final PersonaService personaService;

    @Autowired
    public PersonaRestController(PersonaService personaService){
        this.personaService = personaService;
    }

    @DeleteMapping(value="/{id}")
    public ResponseEntity<Void> deleteOne(@PathVariable String id){
        personaService.deleteOne(id);
        return ResponseEntity.noContent().build();
    }

    ....

this.メソッド呼び出しの実行に使用していないことがわかります。

4

1 に答える 1

1

問題はあなたのpointcut定義にあるようです。あなたのアドバイス メソッドは、1 つのパラメーターを持つメソッドに対してのみ実行されることに気付くかもしれません。これはargs(id)、ポイントカット宣言で指定したという事実によるものです。を削除すると期待どおりに動作するはずですargs(id)が、この場合、パラメーター値を公開するためにいくつかの回避策を使用する必要があります。

のような構造は、すべてのメソッドを最初のパラメーターでexecution(* *.*(String, ..)) && args(arg) && target(t))キャプチャして に公開するという明確な意味を持っているため、これは AspectJ からの奇妙な動作だと思います。少なくとも AspectJ 開発者にとっては、バグまたは機能である可能性があります。Stringargs

joinPoint.getArgs()必要なものを取得するには、次のような内部アドバイス メソッドで回避策を使用できます。

@Pointcut(value=
"execution(* com.manuel.jordan.controller.*.*Controller.deleteOne(..)) && target(object)")
public void deleteOnePointcut(Object object){}

@Before(value="ControllerPointcut.deleteOnePointcut(object)")
public void beforeAdviceDeleteOne(JoinPoint jp, Object object){
    Object id = jp.getArgs()[0];
    logger.info("beforeAdviceDeleteOne - @Controller: {} - Method: deleteOne - id: {}", object.getClass().getSimpleName(), id);
}
于 2016-09-29T03:51:46.107 に答える