How to configure controller in spring without component scanning in xml?

11,479

Solution 1

The problem why you get 404 - Not Found is use of tag <context:annotation-config/> only.

<context:annotation-config/> only activates the annotation on the beans which are already registered with your application context and does basic autowiring for you. It does not auto-detect and register beans.

So there are no as such no Controllers available for you to handle request.

In order to configure controllers you either switch back to context:component-scan which anyways is working for you (do consider taking M. Deinum suggestion while reverting) or manually configure the controllers to respective URL's via HandlerMappings such as SimpleUrlHanslerMapping (not recommended due to verbosity involved)

P.S.: Do read this fabulous post discussing the differences between <context:annotation-config> and <context:component-scan>

Solution 2

How can I configure the controller without component scanning in XML?. you can use annotation based configuration to avoid XML.

check this EnableWebMvc configuration. I configured a spring3.2 project without xml configuration. it was totally annotation based.

overwrite startup of web application Initializer :

public class Initializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException 
    {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(WebAppConfig.class);
        ctx.setServletContext(servletContext);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        servletContext.addListener(new ContextLoaderListener(ctx));        
    }
}

Configuration file for application context

@Configuration
@ComponentScan("com.paul.nkp")     // set your root package, it will scan all sub-package
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:com/paul/nkp/application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {

    /**
     * configured for read property values using @Value attibutes
     *
     * @return
     */
    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean(name = "multipartResolver")
    public static MultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }
    @Bean
    public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException, IOException {
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        ......
        sessionFactoryBean.setHibernateProperties(getHibernateProperties());
        System.out.println("Session Factory Init");

        return sessionFactoryBean;
    }
}

Now everything in code, no xml manipulation. There is a ComponentScan annotation in configuration file, which scan all spring annotation from you base package.

Share:
11,479
Hasib Tarafder
Author by

Hasib Tarafder

Always seeking for new &amp; efficient technologies in Web for implementing my ideas

Updated on June 08, 2022

Comments

  • Hasib Tarafder
    Hasib Tarafder almost 2 years

    I have to design a very large scale project for a bank using spring mvc. I already choose to go with the XML configuration. My concern is to limit the start up time of the server. There will be approximately 2000 controllers.

    I already use component scan for scanning the @Controller. It worked fine. But, the problem is when I remove the component scan from XML and add the controller bean using bean configuration manually in XML, it didn't create the instance of controller in IOC container. And gives me the 404 not found error. So how can I configure the controller without component scanning in XML.

    Followings are my code samples. Any help?

    servlet-context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:annotation-config/>
    
        <mvc:resources mapping="/resources/**" location="/resources/" />
    
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/pages/" />
            <property name="suffix" value=".jsp" />
        </bean>
    
        <!--<context:component-scan base-package="" />-->
    </beans>
    

    root-context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <import resource="dataContext/data-context.xml" />
    
        <bean id="contactSetupController" class="com.stl.afs.ci.cca.controller.ContactSetupController">
            <property name="contactSetupDao" ref="contactSetupDao" />
        </bean>
    
        <bean id="contactSetupDao" class="com.stl.afs.ci.cca.controller.ContactSetupDao" scope="prototype">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
    </beans>
    

    ContactSetupController.java

    package com.stl.afs.ci.cca.controller;
    
    import org.hibernate.Query;
    import org.hibernate.SessionFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    
    @Controller
    @RequestMapping("/contactsetup")
    public class ContactSetupController {
        private static final Logger logger = LoggerFactory.getLogger(ContactSetupController.class);
    
    
        private ContactSetupDao contactSetupDao;
    
        public void setContactSetupDao(ContactSetupDao contactSetupDao) {
            this.contactSetupDao = contactSetupDao;
        }
    
        @RequestMapping(method = RequestMethod.GET)
        public String index(ModelMap model) {
            contactSetupDao.showDepedency();
    
            model.addAttribute("message", "Hello world! Nice to see you in the planet");
            return "ci/contactsetup/index";
        }
    }
    

    ContactSetupDao.java

    package com.stl.afs.ci.cca.controller;
    
    import org.hibernate.Query;
    import org.hibernate.SessionFactory;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    /**
     * Created by ARNAB on 1/8/2015.
     */
    public class ContactSetupDao {
        public ContactSetupDao() {
            System.out.println("------DAO------");
        }
    
        private SessionFactory sessionFactory;
    
        public void setSessionFactory(SessionFactory sessionFactory) {
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@" + sessionFactory);
            this.sessionFactory = sessionFactory;
        }
    
        @Transactional(readOnly = true)
        public void showDepedency(){
            Query query = sessionFactory.getCurrentSession().createSQLQuery("SELECT * FROM customers");
            int i = 0;
            for (Object o : query.list()) {
                i++;
            }
            System.out.println(i);
        }
    
    }