Search code examples
springaopspring-aop

Spring AOP apply to all methods that are not final


I have the following Aspect...

@Aspect
@Component
public class RestrictAspect {

    protected static final Logger logger = LoggerFactory.getLogger(RestrictAspect.class);

    @Pointcut(value = "execution(public * *(..))")
    public void allMethods() {
    }

    @Around("allMethods() && @annotation(restrict)")
    public Object checkAuthorization(ProceedingJoinPoint pjp, Restrict restrict) throws Throwable {
        if (pjp != null && restrict != null && restrict.toRole() >= 0) {

            // get the session info -> then the users
            SessionInformation si = (SessionInformation) FacesContext.getCurrentInstance()
                    .getExternalContext()
                    .getSessionMap()
                    .get(XxxConstants.SESSION_SESSIONINFO);

            if (si == null || si.getUser() == null) {
                final String msg = "No authenticated user found.";
                logger.warn("Throwing InvalidAccessException: {}", msg);
                throw new InvalidAccessException(msg);
            }

            final User user = si.getUser();

            if (!user.isAccountAdmin()) {
                final String msg = "User is not an administrator.";
                logger.warn("Throwing InvalidAccessException: {}", msg);
                throw new InvalidAccessException(msg);
            }

            if (AdminUserRoles.hasRightsTo(user.getRole(), restrict.toRole())) {
                return pjp.proceed();
            } else {
                final String msg = "User does not have access to " + getRoleName(restrict.toRole(), new StringLanguage(MESSAGES, Locale.getDefault())) + "(" + restrict.toRole() + ")";
                logger.warn("Throwing InvalidAccessException: {}", msg);
                throw new InvalidAccessException(msg);
            }
        }
        final String msg = "Unable to grant access.";
        logger.warn("Throwing InvalidAccessException: {}", msg);
        throw new InvalidAccessException(msg);
    }
}

The problem is that it is attempting to apply the aspect to my final methods in my classes, and throwing the following warnings:

07 Apr 2019 02:47:11  INFO o.s.a.f.CglibAopProxy:266 [admin@test.com @ 1] - Final method [protected final javax.servlet.http.HttpServletRequest net.xxxx.beans.XxxBean.getHttpServletRequest()] cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance.
07 Apr 2019 02:47:11  INFO o.s.a.f.CglibAopProxy:266 [admin@test.com @ 1] - Final method [public final java.lang.String net.xxxx.beans.XxxBean.getTimeZone()] cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance.
07 Apr 2019 02:47:11  INFO o.s.a.f.CglibAopProxy:266 [admin@test.com @ 1] - Final method [protected final void net.zzz.beans.XxxBean.log(java.lang.String)] cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance.

All the errors are due to a series of final methods that are defined in a base class that the Aspect is being applied to. Is there any way to write my PointCut / execution() to have it not attempt to apply this to final methods to remove my errors and clean up my logs?

Thanks!


Solution

  • What you see are not errors, just warnings. Still, it makes sense to be more precise with your pointcut, as you suggested:

    @Pointcut(value = "execution(public !final * *(..))")
    public void nonFinalPublicMethods() {}
    

    BTW, if you would switch from Spring AOP to AspectJ you could also weave final methods because AspectJ does not rely on dynamic proxies.