Jack
Jack

Reputation: 1

Cannot get rid of @Autowired by using @RequiredArgsConstructor or @AllArgsConstructor

I have the following code:

// @RequiredArgsConstructor
// @AllArgsConstructor
@NoArgsConstructor
public class AuthTokenFilter extends OncePerRequestFilter {

    @Autowired
    private final JwtUtils jwtUtils;
    // private final JwtUtils jwtUtils;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    // private final UserDetailsServiceImpl userDetailsService;

    private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
        HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            String jwt = parseJwt(request);
            if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
                String username = jwtUtils.getUserNameFromJwtToken(jwt);

                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(
                                userDetails,
                                null,
                                userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            logger.error("Cannot set user authentication: {}", e);
        }

        filterChain.doFilter(request, response);
    }

    private String parseJwt(HttpServletRequest request) {
        String headerAuth = request.getHeader("Authorization");

        if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
            return headerAuth.substring(7, headerAuth.length());
        }

        return null;
    }
}

I am trying to get rid of @Autowired by using @RequiredArgsConstructor or @AllArgsConstructor as commented in the code. However, as the final fields may not been initialized, I get error indicating this problem. For that, I may also set jwtUtils and userDetailsService as null, but I am not sure if it is a good idea. So, can I use a constructor annotation (lombok) to get rid of @Autowired in this example?

Update: When using the suggested approach, I get error in this bean in other class:

@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
    return new AuthTokenFilter();
}

Expected 2 arguments but found 0 error

Upvotes: 1

Views: 1828

Answers (2)

Sandeep Kumar
Sandeep Kumar

Reputation: 35

Starting with Spring version 4.3, the single bean constructor does not need to be annotated with the @Autowired annotation. With Lombok, it's possible to generate a constructor for either all class's fields (with @AllArgsConstructor) or all final class's fields (with @RequiredArgsConstructor).

Upvotes: 0

Chaosfire
Chaosfire

Reputation: 6985

Just use constructor injection. If your bean has exactly one constructor, spring will behave as if it has @Autowired, even if it's not added explicitly.

@AllArgsConstructor
@Component
public class AuthTokenFilter extends OncePerRequestFilter {

    private final JwtUtils jwtUtils;
    private final UserDetailsServiceImpl userDetailsService;

    private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        //method implementation
    }
}

Edit: Add @Component on the class, spring will initialize the bean for you, no need to do it manually with @Bean (remove the entire method).

Upvotes: 1

Related Questions