【问题标题】:Spring Bean injection in web applicationWeb应用程序中的Spring Bean注入
【发布时间】:2013-11-10 09:19:46
【问题描述】:

spring控制器处理请求时,服务不连线:

@Controller
@RequestMapping(value = "/login")
public class LoginController {

    @Inject
    private AccountService accountService;

    @RequestMapping(method = RequestMethod.POST)
    public String handleLogin(HttpServletRequest request, HttpSession session){
        try {
            ...
            //Next line throws NullPointerException, this.accountService is null
            Account account = this.accountService.login(username, password);
        } catch (RuntimeException e) {
            request.setAttribute("exception", e);
            return "login";
        }
    }
}

AccountService 及其唯一的实现在模块service 中定义为:

package com.savdev.springmvcexample.service;
...
public interface AccountService {

...

package com.savdev.springmvcexample.service;
@Service("accountService")
@Repository
@Transactional
public class AccountServiceImpl implements AccountService {

网页配置通过文件加载,位于web模块:

    package com.savdev.springmvcexample.web.config;
    public class SpringMvcExampleWebApplicationInitializer implements WebApplicationInitializer 

{

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        registerDispatcherServlet(servletContext);
    }

    private void registerDispatcherServlet(final ServletContext servletContext) {
        WebApplicationContext dispatcherContext = createContext(WebMvcContextConfiguration.class);
        ...
    }
    private WebApplicationContext createContext(final Class<?>... annotatedClasses) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(annotatedClasses);
        return context;
    }

将包扫描到发现 bean 的 WebMvcContextConfiguration 文件:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.savdev.springmvcexample.web", "com.savdev.springmvcexample.service" })
public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setOrder(1);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}

加载了这个类,导致视图解析是根据 InternalResourceViewResolver 逻辑使用的。结果,扫描了“com.savdev.springmvcexample.web”,因为找到了处理请求的控制器。

扫描了“com.savdev.springmvcexample.service”,但它在另一个模块中,我不知道这是否是一个问题,但我没有收到任何错误。

更新:

@JBNizet, module - 表示 maven 多模块项目中的模块。我已经删除了@Repository,现在我在测试中遇到错误:

NoSuchBeanDefinitionException: 没有符合条件的 bean 类型 [javax.sql.DataSource] 找到依赖项。

这意味着,这意味着弹簧配置文件未激活。仅为配置文件加载数据源。

在网络基础设施中,我使用以下方式管理配置文件:

public class SpringMvcExampleProfilesInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {

    @Override
    public void initialize(ConfigurableWebApplicationContext ctx) {
        ConfigurableEnvironment environment = ctx.getEnvironment();
        List<String> profiles = new ArrayList<String>(getProfiles());
        if( profiles == null || profiles.isEmpty() )
        {
            throw new IllegalArgumentException("Profiles have not been configured");
        }
        environment.setActiveProfiles(profiles.toArray( new String[0]));
    }

    //TODO add logic
    private Collection<String> getProfiles() {
        return Lists.newArrayList("file_based", "test_data");
    }
}

如果我没记错的话 SpringMvcExampleProfilesInitializer 在 Spring ApplicationContext 加载之前使用。它是自动制作的。无需为此配置任何其他内容。但它不起作用。如果我错了,请纠正我。

请注意,初始化器具有以下签名:

SpringMvcExampleProfilesInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext>

在配置 DispatcherServlet 的那一刻,我可以使用:

setContextInitializers(ApplicationContextInitializer<ConfigurableApplicationContext>... contextInitializers) 

如何设置 setContextInitializers 但传递实现 ApplicationContextInitializer&lt;ConfigurableWebApplicationContext&gt; 而不是 ApplicationContextInitializer&lt;ConfigurableApplicationContext&gt; 的东西

【问题讨论】:

  • 什么叫“模块”?是“包裹”吗?为什么您的服务使用@Repository 进行注释?不应该。
  • @JBNizet,模块 - 多模块 maven 项目的模块,我删除了“@Repository”,并更新了我的问题。此处无法插入。

标签: java spring spring-mvc configuration autowired


【解决方案1】:

@Inject 要求在类路径中存在 JSR 330 jar。可能是它在编译时可见,但在运行时不可见。

试试这个:

@Autowired(required=true)
private AccountService accountService;

如果这不起作用,则表示未正确扫描 bean AccountServiceImpl。

如果它确实有效,则意味着@Inject 支持存在问题(可能在运行时缺少 jar)。

如果扫描不起作用,请尝试通过xml进行扫描:

<context:component-scan base-package="com.savdev.springmvcexample.service" />

你能回帖吗:

  • 如果 @Autowired(required=true) 有效
  • 是否以及如何在 poms 中添加 JSR-330(mvn 依赖关系的输出:树)
  • 通过 xml 扫描是否有效

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2022-12-01
    • 2023-03-30
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多