ожидается как минимум 1 компонент, который квалифицируется как кандидат на автоматическое подключение. Аннотации зависимостей

#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.