#java #spring #spring-mvc
#java #весна #spring-mvc
Вопрос:
Я использую конфигурацию на основе Java. У меня есть следующая настройка кода, которая показывает ошибку.
public class MyWebInitializer implements WebApplicationInitializer {
public static Logger logger = Logger.getLogger(MyWebInitializer.class);
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
logger.info("initializing web context");
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.register(FrontController.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher",
new DispatcherServlet(annotationConfigWebApplicationContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
logger.info("On start up method complete");
}
}
Настройка переднего контроллера:
@Configuration
@EnableWebMvc
@ComponentScan("com.ishwor.crm.controller,com.ishwor.crm.entity,com.ishwor.crm.DAO")
@PropertySource("classpath:hibenrate.properties")
@EnableTransactionManagement
public class FrontController implements WebMvcConfigurer {
public static Logger logger = Logger.getLogger(FrontController.class);
@Autowired
Environment environment;
@Bean
InternalResourceViewResolver internalResourceViewResolver() {
logger.info("inside view resolver function ");
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
logger.info("View Resolving complete ");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.info("Inside static resource handler");
// for css and js
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());
logger.info("static resource handling complete");
}
// hibernate configuration
@Bean(name = "sessionFactory")
public LocalSessionFactoryBean sessionBean() {
logger.info("Creating sesion bean");
LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
bean.setDataSource(dataSource());
bean.setPackagesToScan(
new String[] { "com.ishwor.crm.entity", "com.ishwor.crm.DAO", "com.ishwor.crm.DAOImpl" });
bean.setHibernateProperties(hibernateProperties());
logger.info("Creating sesion bean=== successfull!!!");
return bean;
}
@Bean
public DataSource dataSource() {
logger.info("Datasource method invoked");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
logger.info("DataSource Invoke complete");
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
logger.info("setting properties for hibernated");
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
logger.info("setting properties completed");
return properties;
}
@Bean
public HibernateTransactionManager getTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionBean().getObject());
return transactionManager;
}
}
Entity Setp:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Customer() {
}
public Customer(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
@Override
public String toString() {
return "Customer [id=" id ", firstName=" firstName ", lastName=" lastName ", email=" email "]";
}
}
Настройка DAO:
package com.ishwor.crm.DAO;
import java.util.List;
import com.ishwor.crm.entity.Customer;
public interface CustomerDAO {
public List<Customer> getCustomer();
}
DAOImpl setup
package com.ishwor.crm.DAOImpl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.ishwor.crm.DAO.CustomerDAO;
import com.ishwor.crm.entity.Customer;
@Repository
public class CustomerDAOImpl implements CustomerDAO {
@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessionFactory;
public CustomerDAOImpl() {
}
@Override
@Transactional
public List<Customer> getCustomer() {
// get current hibernate Session
Session currenSession = sessionFactory.getCurrentSession();
// create Query
Query<Customer> myQuery = currenSession.createQuery("from customer", Customer.class);
// execute query and get result
return myQuery.getResultList();
}
}
Но использование этого DAO в качестве Autowired показывает ошибку, которую я получаю после настройки CustomerController:
package com.ishwor.crm.controller;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ishwor.crm.DAO.CustomerDAO;
import com.ishwor.crm.entity.Customer;
@Controller()
@RequestMapping("/customer")
public class CustomerController {
public static Logger logger = Logger.getLogger(CustomerController.class);
// Autowired customerDAO
@Autowired
private CustomerDAO customerDAO;
@RequestMapping("/list")
public String customerHome(Model model) {
logger.info("customer index metho browsed");
List<Customer> customer = customerDAO.getCustomer();
model.addAttribute("customer", customer);
return "/customer/index";
}
}
Обратите внимание, что без автоматического подключения код класса контроллера работает нормально.
Должен ли я использовать аннотацию @service, используя для этой работы еще один класс и интерфейс.
Комментарии:
1. Пожалуйста, добавьте журнал исключений в вопрос.
Ответ №1:
Не удалось выполнить сканирование компонентов.
Добавьте com.ishwor.crm.DAOImpl
пакет @ComponentScan
в код :
@ComponentScan("com.ishwor.crm.controller,com.ishwor.crm.entity,com.ishwor.crm.DAO,com.ishwor.crm.DAOImpl")
CustomerDAOImpl
Заменить CustomerDAO
на CustomerController
. Это будет работать.
@Autowired
private CustomerDAO customerDAO;
Ответ №2:
Я думаю, что Spring по умолчанию использует автоматическое подключение по имени. Вам либо нужно переименовать локальную переменную контроллера в «… Impl», либо вам нужно переопределить имя по умолчанию класса Impl.
Комментарии:
1. Спасибо за ответ. Я попробовал оба варианта, ни один из них не работает, все та же ошибка.
Ответ №3:
Похоже, что ваш customerDaoImpl не сканируется spring для обработки аннотаций. Проверьте свою конфигурацию, @Autowired автоматически разрешится по типу компонента. Таким образом, автоматическое подключение выполнено правильно, ваша конфигурация, которая не сканирует аннотацию @Repository, и, следовательно, не создает ее компонент
Комментарии:
1. Прямо сейчас я использую это
@ComponentScan("com.ishwor.crm.controller,com.ishwor.crm.entity,com.ishwor.crm.DAO,com.ishwor.crm.DAOImpl")
, и теперь код ошибки: «Компонент с именем customerDAOImpl», как ожидается, будет иметь тип com.ishwor.crm. DaoImpl.CustomerDAOImpl’ но на самом деле был типа ‘com.sun.proxy. $Proxy130’ `
Ответ №4:
Для сканирования нескольких пакетов используйте String array, как показано ниже:
@ComponentScan({"com.ishwor.crm.controller","com.ishwor.crm.entity","com.ishwor.crm.DAO"})
Комментарии:
1. Прямо сейчас я использую это
@ComponentScan({ "com.ishwor.crm.controller,com.ishwor.crm.entity,com.ishwor.crm.DAO,com.ishwor.crm.DAOImpl" })
2. Используя это прямо сейчас:
@ComponentScan({ "com.ishwor.crm.controller,com.ishwor.crm.entity,com.ishwor.crm.DAO,com.ishwor.crm.DAOImpl" })
и код ошибки :Bean named 'customerDAOImpl' is expected to be of type 'com.ishwor.crm.DAOImpl.CustomerDAOImpl' but was actually of type 'com.sun.proxy.$Proxy165'
Ответ №5:
да, вы должны попробовать этот класс @Service всякий раз, когда вам нужно кэшировать данные, лучше кэшировать данные в классе service последним, но не в списке @Repository @Service @Controller эти 3 являются специализированными @Component, если вы используете их правильно, это также называется 3-уровневой архитектурой . если ваши проекты будут большими, это вам очень поможет.бизнес-логика должна быть в классе service.