リクエストがスプリング コントローラーによって処理されるとき、サービスは配線されません。
@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
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、モジュール - 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>