java 如何在没有xml组件扫描的情况下在spring中配置控制器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27847237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:30:38  来源:igfitidea点击:

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

javaspringspring-mvcdependency-injectioncomponent-scan

提问by Hasib Hasan Arnab

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.

我必须使用 spring mvc 为银行设计一个非常大规模的项目。我已经选择使用 XML 配置。我关心的是限制服务器的启动时间。将有大约 2000 个控制器。

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.

我已经使用组件扫描来扫描@Controller. 它工作得很好。但是,问题是当我从 XML 中删除组件扫描并在 XML 中使用 bean 配置手动添加控制器 bean 时,它没有在 IOC 容器中创建控制器的实例。并给我 404 not found 错误。那么如何在没有 XML 组件扫描的情况下配置控制器。

Followings are my code samples. Any help?

以下是我的代码示例。有什么帮助吗?

servlet-context.xml

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

<?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

联系人设置控制器.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

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

}

回答by Bond - Java Bond

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

您得到的问题404 - Not Found<context:annotation-config/>使用 tag 。

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

<context:annotation-config/>仅激活已在您的应用程序上下文中注册的 bean 上的注释,并为您执行基本的自动装配。它不会自动检测和注册 bean。

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

因此Controllers,您无法处理请求。

In order to configure controllers you eitherswitch back to context:component-scanwhich anyways is working for you (do consider taking M. Deinum suggestion while reverting) ormanually configure the controllers to respective URL's via HandlerMappingssuch as SimpleUrlHanslerMapping(not recommended due to verbosity involved)

为了配置控制器,你要么切换回context:component-scan这反正是为你工作(不考虑采取M. Deinum建议同时恢复或者通过手动配置控制器,以各自的URL HandlerMappings,例如SimpleUrlHanslerMapping不推荐,因为涉及冗长

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

PS:请阅读这篇精彩的帖子,讨论<context:annotation-config><context:component-scan>

回答by Nikson Kanti Paul

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

How can I configure the controller without component scanning in XML?. 您可以使用基于注释的配置来避免 XML。

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

检查此EnableWebMvc配置。我配置了一个没有xml配置的spring3.2项目。它完全基于注释。

overwrite startup of web application Initializer:

覆盖 Web 应用程序的启动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 ComponentScanannotation in configuration file, which scan all spring annotation from you base package.

现在一切都在代码中,没有 xml 操作。ComponentScan配置文件中有一个注释,它会扫描您基础包中的所有 spring 注释。