Bean无法在类中自动装配

时间:2017-04-22 09:14:44

标签: java spring

我使用JWT (Json Web Token)来保护我的Spring启动应用程序。

有一个不接受任何bean的课程。

首先,我想也许我想要注入的bean没有定义。所以我决定使用spring ApplicationContext打印bean名称列表。但我发现即使ApplicationContext也不能注入这个类:

知道为什么会这样吗?

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Arrays;

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    @Autowired
    private TokenAuthenticationService tokenAuthenticationService;

    @Autowired
    private ApplicationContext applicationContext;

    public JWTLoginFilter(String url, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(url));
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest req,
            HttpServletResponse res) throws AuthenticationException,
            IOException, ServletException {

        CustomUserDetails creds = new ObjectMapper().readValue(
                req.getInputStream(), CustomUserDetails.class);

        return getAuthenticationManager().authenticate(
                new UsernamePasswordAuthenticationToken(creds.getUsername(),
                        creds.getPassword()));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest req,
            HttpServletResponse res, FilterChain chain, Authentication auth) {
        java.util.List s = Arrays.asList(applicationContext.getBeanDefinitionNames());
        System.out.println(s);
        tokenAuthenticationService.addAuthentication(res, auth.getName());
    }
}

2 个答案:

答案 0 :(得分:3)

JWTLoginFilter也必须是一个bean,以允许Spring注入其他bean。目前,Spring对此没有任何控制权。使用@Component / @Service / @Repository注释标记班级(取决于您的过滤器扮演的角色,我认为@Component是一个不错的选择)将解决问题。

编辑1:

  

JWTLoginFilter需要找不到类型java.lang.String的bean。组件可以有构造函数吗?

问题:Spring试图使用双参数构造函数来创建一个bean,并且期望这两个参数是它的bean。但事实并非如此,因为没有String类的bean。

解决方案:您应该定义一个非参数构造函数,以允许Spring在没有问题的情况下创建一个未调整的实例。然后创建setter以提供Spring将用于注入所需依赖项的方法。

编辑2:

解决方法是定义一个String bean(在@Configuration类中),它将被注入JWTLoginFilter构造函数,但我不确定你的过滤器是否需要一些外部依赖。

@Bean
public String getStringPatternBean() {
    return "pattern";
}

答案 1 :(得分:0)

好吧,我终于决定改变这些类的设计方式。我在TokenAuthenticationService静态内部创建了方法。