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

情到浓时终转凉″ 提交于 2020-01-23 13:52:10

问题


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);
    }

}

回答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>




回答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.



来源:https://stackoverflow.com/questions/27847237/how-to-configure-controller-in-spring-without-component-scanning-in-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!