0

リクエストがスプリング コントローラーによって処理されるとき、サービスは配線されません。

@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 {

webWeb 構成は、次のモジュールにあるファイルによってロードされます。

    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、モジュール - Maven マルチモジュール プロジェクトのモジュールを意味します。@Repository を削除したところ、テストでエラーが発生しました。

NoSuchBeanDefinitionException: 依存関係のタイプ [javax.sql.DataSource] の適格な Bean が見つかりません。

つまり、スプリング プロファイルがアクティブ化されていないことを意味します。DataSource は、プロファイルに対してのみロードされます。

Web インフラストラクチャでは、次を使用してプロファイルを管理します。

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");
    }
}

私が間違っていなければ、Spring ApplicationContext がロードされる前に SpringMvcExampleProfilesInitializer が使用されます。そしてそれは自動的に作られます。これには、追加の設定は必要ありません。しかし、それは機能していません。私が間違っている場合は、私を修正してください。

初期化子には次の署名があることに注意してください。

SpringMvcExampleProfilesInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext>

DispatcherServlet が構成されている時点で、次を使用してセットアップできます。

setContextInitializers(ApplicationContextInitializer<ConfigurableApplicationContext>... contextInitializers) 

ApplicationContextInitializer<ConfigurableWebApplicationContext>setContextInitializers をセットアップする方法ApplicationContextInitializer<ConfigurableApplicationContext>

4

1 に答える 1

0

@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) が機能する場合
  • JSR-330 が poms に追加された場合とその方法 (mvn dependency:tree の出力)
  • xml を介したスキャンは機能しましたか
于 2013-11-10T13:44:25.490 に答える