Имеется простенькое приложение, написанное с использованием Spring MVC Нахожусь на этапе изучения фреймворка. Просьба жестко не критиковать, если найдутся большие недочёты.
Суть приложения проста: можем добавить нового пользователя в базу и по возможности вывести список всех пользователей в базе. Ничего сложного.
В процессе разработки не использовал .xml конфигурации. Только лишь Java config. Всё работало прекрасно до того, как попытался прикрутить слой service.
Код представлен ниже:
RootConfig.javapackage ru.nw.mvc.config;
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {
"ru.nw.mvc.controller",
"ru.nw.mvc.model",
"ru.nw.mvc.repository",
"ru.nw.mvc.service"})
public class RootConfig {
}
WebMvcConfig.javapackage ru.nw.mvc.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableWebMvc
@EnableJpaRepositories(basePackages = {"ru.nw.mvc.repository"}, entityManagerFactoryRef = "entityManagerFactory")
@ComponentScan(basePackages = {
"ru.nw.mvc.controller",
"ru.nw.mvc.model",
"ru.nw.mvc.repository",
"ru.nw.mvc.service"})
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry handlerRegistry) {
handlerRegistry.addResourceHandler("/css/**").addResourceLocations("/resources/css/");
handlerRegistry.addResourceHandler("/js/**").addResourceLocations("/resources/js/");
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306");
dataSource.setUsername("root");
dataSource.setPassword("");
return dataSource;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan("ru.nw.mvc.model");
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
}
AppInit.javapublic class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
UserRepository.javapackage ru.nw.mvc.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.nw.mvc.model.User;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {
void addUser(User user);
List<User> getAll();
}
HelloController.javapackage ru.nw.mvc.controller;
import ru.nw.mvc.model.User;
import ru.nw.mvc.service.UserService;
import java.util.List;
@Controller
@RequestMapping("/")
@ComponentScan(basePackages = {"ru.nw.mvc.service", "ru.nw.mvc.service.userService", "ru.nw.mvc.controller"})
public class HelloController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Hello, world!");
return "main";
}
@RequestMapping(method = RequestMethod.POST, value = "addUser")
public String addUser(@ModelAttribute("firstname") String login,
@ModelAttribute("lastname") String password, ModelMap model) {
userService.addUser(new User(login, password));
List<User> users = userService.getAll();
model.addAttribute("user", users);
return "list";
}
}
Класс
UserService.javapackage ru.nw.mvc.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.nw.mvc.model.User;
import ru.nw.mvc.repository.UserRepository;
import java.util.List;
@Service
public class UserServiceImpl implement UserService {
public void addUser(User user) {
userRepository.save(user);
}
public List<User> getAll() {
return userRepository.findAll();
}
@Autowired
private UserRepository userRepository;
}
public interface UserService {
public void addUser(User user);
public List<User> getAll();
}
При деплое приложения выбрасывается куча ошибок в трейс
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.nevweather.mvc.service.UserService ru.nevweather.mvc.controller.HelloController.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.nevweather.mvc.repository.UserRepository ru.nw.mvc.service.UserServiceImpl.userRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [ru.nw.mvc.repository.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.nw.mvc.service.UserService ru.nevweather.mvc.controller.HelloController.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.nw.mvc.repository.UserRepository ru.nevweather.mvc.service.UserServiceImpl.userRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [ru.nw.mvc.repository.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.nevweather.mvc.repository.UserRepository ru.nw.mvc.service.UserServiceImpl.userRepository;
2ой день не могу разобраться в чём причина. Пытался в проекте менять расположение сервисов, контроллеров, а также прописывал соответствующие пути в конфигах, но безрезультатно. Есть мысль, что даже с теми путями, что прописаны в качестве базовых директории, где хранятся controller'ы, servic'ы, фреймворк не видит классы.
P.S.
IDE - IDEA 14. Проект был с xml-конфигами, но я решил отказаться от них в сторону Jav'овских конфигов. При их написании начались проблемы с деплоем. Проблема была решена удалением конфигов из Facets (см. скриншот)