Весенний регистратор аспектов

Я создавал определение аспекта на основе аннотации, поэтому создаю @LogPerformance и помещаю его в метод createuser(). В этом случае он не вызывает метод аспекта. Но когда я переместил @LogPerformance из createuser() в метод create(), вызывается метод аспекта. Почему @LogPerformance не влияет на метод createuser.

@Component
@Path(SystemConstants.REST_REGISTER)
public class RegisterServices { 

@PUT
    @Path(SystemConstants.REST_REGISTER_CREATE)
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces({MediaType.APPLICATION_JSON}) 
    public Response create(@Context HttpServletRequest requestContex) String requestIp, String param) {

        createUser(...);

    }


    @LogPerformance
    public ClientRespWsBean createUser(ClientReqWsBean request) throws XMPPException
    {

    }

}

person Ahmet Karakaya    schedule 27.01.2015    source источник
comment
Я думаю, что если createUser() не находится в классе RegisterServices, он будет вызван   -  person Ahmet Karakaya    schedule 27.01.2015
comment
из кода, который вы разместили, кажется, что вызов createUser происходит внутри RegisterServices, поэтому это простой вызов API. Однако, как вы уже отметили в комментариях, createUser вызывается из другого управляемого bean-компонента Spring, он ударит по аспекту @LogPerformance   -  person Bond - Java Bond    schedule 27.01.2015


Ответы (1)


Я предполагаю, что мы используем AOP на основе прокси-сервера Springs (вы не опубликовали свою конфигурацию, поэтому я должен догадаться).

Этот AOP на основе прокси работает только тогда, когда рекомендуемый метод вызывается непосредственно из другого компонента (потому что тогда также вызывается прокси). Но когда вы вызываете рекомендуемый метод из того же bean-компонента (через this), то прокси-сервер не вызывается, и поэтому аспект не выполняется. (@см. Справочник по Spring, Глава 9.6.1 Понимание прокси АОП)

Есть два решения:

пример:

public class RegisterServices {
    /*
     * You must use @Resource instead of @Autowire 
     * https://jira.spring.io/browse/SPR-8450
     * (and of course you need to enable @Resourse support first)
     */
    @Resource private RegisterServices self; //self reference with proxy
    ...

    public Response create(...) {
        this.self.createUser(...);
    }

    @LogPerformance
    public ClientRespWsBean createUser(...){...}
}

Я предпочитаю способ AspectJ, потому что при использовании способа ссылки на себя можно забыть использовать его

person Ralph    schedule 27.01.2015
comment
да, это единственный способ, которым мой код работает правильно. Но в этом случае необходимо изменить очень похожий блок кода, что означает дополнительные накладные расходы на написание кода. - person Ahmet Karakaya; 27.01.2015