66

数日前、私はこの Spring Hello World チュートリアルの勉強を始めました: http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/

このチュートリアルでは、Spring DispatcherServlet は、次のspring-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.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="net.viralpatel.spring3.controller" />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

このファイルでは、context:component-scanタグを使用して、Spring が注釈を検索してファイルをスキャンする必要があることを示しています。たとえば、コントローラ クラスが@RequestMapping("/hello")注釈によってメソッドに注釈が付けられていることを検出した場合などです。このメソッドが「/hello」で終わる URL への HTTP リクエストを処理することがわかっています。これは簡単です...

私の疑問は、STS\Eclipse で自動的にビルドできる Spring MVC テンプレート プロジェクトに関連しています。

STS で新しい Spring MVC プロジェクトを作成すると、私のDispatcherServletは、前のサンプル ファイルと同様の構成を含むservlet-context.xmlという名前のファイルによって構成されます。

このファイルには、まだコンポーネント スキャン タグがあります。

<context:component-scan base-package="com.mycompany.maventestwebapp" />

しかし、別のタグ(同様のタスクがあるように見える)もあります。これは次のとおりです。

<annotation-driven />

この 2 つのタグの違いは何ですか?
もう 1 つの「奇妙な」点は、前の例 (アノテーション駆動タグを使用しない) が、Spring MVC テンプレート プロジェクトを使用して STS によって作成されたプロジェクトに非常に似ていることですが、構成からアノテーション駆動タグを削除すると、プロジェクトが実行されず、次のエラーが表示されます: HTTP ステータス 404 -

そして、私が持っているスタックトレースで:

WARN : org.springframework.web.servlet.PageNotFound - 名前が「appServlet」の DispatcherServlet で、URI [/maventestwebapp/] の HTTP リクエストのマッピングが見つかりません

しかし、なぜ?前の例は、アノテーション駆動型のタグがなくてもうまく機能し、このコントローラー クラスは非常に似ています。実際、「/」パスへの HTTP リクエストを処理するメソッドは 1 つだけです。

これは私のコントローラークラスのコードです:

package com.mycompany.maventestwebapp;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
*/
@Controller
public class HomeController {

private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

/**
 * Simply selects the home view to render by returning its name.
 */
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
    logger.info("Welcome home! The client locale is {}.", locale);

    Date date = new Date();
    DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

    String formattedDate = dateFormat.format(date);

    model.addAttribute("serverTime", formattedDate );

    return "home";
}

誰かがこのことを理解するのを手伝ってくれますか?

どうもありがとうございました!

4

3 に答える 3

85

<mvc:annotation-driven />つまり、実際に XML で一連の要素を指定したり、インターフェイスを実装したり、基本クラスを拡張したりする必要なく、Spring Bean の依存関係を定義できます。たとえば、DaoSupport の他のサブクラス@Repositoryを拡張する必要なく、クラスが Dao であることを春に伝えることができます。JpaDaoSupport同様に@Controller、指定されたクラスには、Controller インターフェイスを実装したり、コントローラーを実装するサブクラスを拡張したりすることなく、Http リクエストを処理するメソッドが含まれていることを Spring に伝えます。

spring が起動すると、XML 構成ファイルを読み取り、その<bean中の要素を探します。何か<bean class="com.example.Foo" />が表示され、Foo がマークアップされて@Controllerいる場合、クラスがコントローラーであることを認識し、そのように扱います。デフォルトでは、Spring は、管理する必要があるすべてのクラスが beans.XML ファイルで明示的に定義されていると想定しています。

を使用したコンポーネント スキャン<context:component-scan base-package="com.mycompany.maventestwebapp" />は、com.mycompany.maventestweapp の下にあるすべてのクラスのクラスパスを検索し、各クラスを調べて、、、、、、、またはが含まれているかどうかを確認し、@Controller含まれ@Repositoryている場合、Spring はそのクラスをXML 構成ファイルに入力したかのように Bean ファクトリを表示します。@Service@Component<bean class="..." />

典型的な Spring MVC アプリでは、2 つの Spring 構成ファイルがあることがわかります。アプリケーション コンテキストを構成するファイルは通常、Spring コンテキスト リスナーで開始されます。

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

また、Spring MVC 構成ファイルは通常、Spring ディスパッチャー サーブレットで開始されます。例えば。

<servlet>
        <servlet-name>main</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>main</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

Spring は階層型 Bean ファクトリをサポートしているため、Spring MVC の場合、ディスパッチャー サーブレット コンテキストはメイン アプリケーション コンテキストの子です。サーブレット コンテキストが「abc」と呼ばれる Bean を要求された場合、最初にサーブレット コンテキストを検索します。そこで見つからない場合は、アプリケーション コンテキストである親コンテキストを検索します。

データ ソース、JPA 構成、ビジネス サービスなどの一般的な Bean はアプリケーション コンテキストで定義されますが、MVC 固有の構成はサーブレットに関連付けられた構成ファイルではありません。

お役に立てれば。

于 2012-12-01T18:34:25.000 に答える
29
<context:component-scan base-package="" /> 

これらのパッケージで注釈をスキャンするよう Spring に指示します。

<mvc:annotation-driven> 

RequestMappingHanderMapping、RequestMappingHandlerAdapter、および ExceptionHandlerExceptionResolver を登録して、MVC に付属する @RequestMapping、@ExceptionHandler などのアノテーション付きコントローラー メソッドをサポートします。

これにより、出力のアノテーション主導の書式設定と、入力のアノテーション主導の検証をサポートする ConversionService も有効になります。また、JSON データを返すために使用できる @ResponseBody のサポートも有効にします。

@Configuration クラスで @ComponentScan(basePackages={"...", "..."} および @EnableWebMvc を使用して、Java ベースの構成を使用して同じことを達成できます。

詳細については、3.1 のドキュメントを参照してください。

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-config

于 2012-12-02T20:44:48.527 に答える
12

アノテーション駆動型は、XML Bean 構成だけに依存するのではなく、アノテーション付き Bean をスキャンする必要があることを Spring に示します。component-scan は、これらの Bean を探す場所を示します。

ここにいくつかのドキュメントがあります:http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-enable

于 2012-12-02T16:15:00.340 に答える