java - 无需组件扫描或 bean 定义即可定义 Controller

标签 java spring spring-mvc

我的代码库中有一个 Controller ,其包未经过组件扫描。该 Controller 也未在任何 XML 的 bean 中定义。

不知何故, Controller 正在工作。我猜这是因为有某种方法可以在 Spring 中定义 Controller ,而无需组件扫描或在 bean 中定义它。然而,这个 Controller 实现了一个名为 AbstractControllerImpl 的类,并且 Helper 实现类正在扫描组件。

Helper 组件被扫描是否意味着 Controller 也会被扫描?或者如果不是,这个 Controller 怎么可能工作?

@Controller
@RequestMapping("/something")
public class SomeController extends AbstractControllerImpl<SomeControllerHelper> {  
    //Some request mappings here
}

它扩展的抽象 Controller 类:

public abstract class AbstractControllerImpl<H extends Helper>
    implements Controller<H>
{    
    private H helper;    

    private BaseValidator validator;

    public H getHelper()
    {
        return helper;
    }

    public void setHelper(H helper)
    {
        this.helper = helper;
    }   

    public void setValidator(BaseValidator validator)
    {
        this.validator = validator;
    }

    public BaseValidator getValidator()
    {
        return validator;
    }

    public Errors doValidation(Object obj)
    {
        Errors validationErrors = new BindException(this, "");
        if (validator != null)
        {
            validator.validate(obj, validationErrors);
        }
        return validationErrors;
    }   
}

Controller 界面:

public interface Controller<H extends Helper>
{
    H getHelper();
}

助手定义:

<?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-3.0.xsd">


   <bean id="someHelper" class="com.controller.SomeHelperImpl" />   

</beans>

帮助器 impl 类(正在扫描组件):

@Component("SomeControllerHelper")
public class ASomeControllerHelperImpl implements SomeControllerHelper {
    //Some methods here
}

编辑:我的 web.xml。我删除了一些 servlet 映射并更改了一些名称,但这就是它的样子:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>SomeApp</display-name>

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<listener>
    <listener-class>
        com.Log4jLoaderServlet
    </listener-class>
</listener>

<context-param>
    <param-name>crossContext</param-name>
    <param-value>true</param-value>
</context-param>

<!-- This listener will load other application context file in addition to springweb-servlet.xml -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- The context params that read by ContextLoaderListener  -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-application-context.xml</param-value>
</context-param>
<!-- Spring security filter -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> 

<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/servlets/rest-servlet.xml</param-value>
    </init-param>       
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>appservlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/servlets/app-servlet.xml</param-value>
    </init-param>       

    <load-on-startup>1</load-on-startup>
</servlet>

<error-page>
    <error-code>404</error-code>        
    <location>/portal/error/notfound/</location>
</error-page>

<error-page>
    <error-code>500</error-code>
    <location>/portal/error/internalsystem/</location>
</error-page>

<jsp-config>
    <taglib>
        <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
        <taglib-location>/WEB-INF/tags/c.tld</taglib-location>
    </taglib>
    <taglib>
      <taglib-uri>http://jakarta.apache.org/taglibs/unstandard-1.0</taglib-uri>
      <taglib-location>/WEB-INF/tld/unstandard.tld</taglib-location>
    </taglib>
</jsp-config>   

这里是app-servlet.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
        <property name="order" value="0" />
    </bean>

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="order" value="1" />
    </bean> 

    <bean  class="org.springframework.web.servlet.view.ResourceBundleViewResolver">

        <property name="basename" value="views"/>
    </bean>

    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
            <property name="definitions">
                <list>                                 
                    <value>/WEB-INF/views/something/views.xml</value>
                    <value>/WEB-INF/views/views.xml</value>
                </list>
            </property>
            <property name="preparerFactoryClass"
                value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory"/>
    </bean>     
</beans>

rest-servlet.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.dw.spring3.rest.controller" />
    <!-- To enable @RequestMapping process on type level and method level -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonConverter" />
            </list>
        </property>
    </bean>

    <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes" value="application/json" />
    </bean>

</beans>

根应用程序-cnntext.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan
        base-package="com.base.notcontroller" />

    <import resource="/something/common-context.xml" />          
</beans>

最佳答案

Does the fact that the Helper is getting component scanned mean the Controller gets scanned too? Or if not, how is it possible that this controller works?

不,这是不可能的。

鉴于您已经完成,目前还不完全清楚您的上下文配置是什么样的

removed a few of the servlet mappings and changed some of the names

但是你的@Controller类必须加载到上下文中的某个位置,可能在

rest-servlet.xml:

其中有

<context:component-scan base-package="com.dw.spring3.rest.controller" />

DispatcherServlet 加载命名`rest .

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/servlets/rest-servlet.xml</param-value>
    </init-param>       
    <load-on-startup>1</load-on-startup>
</servlet>
<小时/>

您可以将无参数构造函数添加到 @Controller 中类并放置一个断点,查看堆栈跟踪并确定它是在哪个上下文中初始化的。

<小时/>

请注意AnnotationMethodHandlerAdapter已在 Spring 3.2 中弃用。考虑使用<mvc:annotation-driven>配置您的 MVC 环境。

关于java - 无需组件扫描或 bean 定义即可定义 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21095515/

相关文章:

java - Selenium 动态生长表

java - 如何像在 Matlab 中一样在 Java 中绘图(相同的语法)

spring - 使用 post 构造测试 spring bean

spring-mvc - 动态页面标题 Thymeleaf Spring MVC

java - 处理来自 @Service 类的 JSP 页面异常

java.lang.ClassNotFoundException : org. springframework.web.context.ContextLoaderListener 问题

java - Liferay Service Builder 中的一对多关系

java - null 和 empty char 在 java 中是相等的

java - 使用 Spring Mvc 测试测试 Spring Security Controller

java - Spring data jpa left join fetch 和 where 子句