18

Spring MVCアプリケーションの特定のURLと一致する、すべてのコントローラーのリストを反射的に取得する方法(注釈が付けられているだけでなく、xmlで指定されている場合に最適)?

注釈付きのみの場合、

@Autowired
private ListableBeanFactory listableBeanFactory;
...
whatever() {
    Map<String,Object> beans = listableBeanFactory.getBeansWithAnnotation(RequestMapping.class);

    // iterate beans and compare RequestMapping.value() annotation parameters
    // to produce list of matching controllers
}

使用することもできますが、より一般的なケースで、spring.xml構成でコントローラーを指定できる場合はどうすればよいですか?そして、リクエストパスパラメータをどうするか?

4

4 に答える 4

32

Spring 3.1以降、クラスがあり、@ ControllerクラスRequestMappingHandlerMappingのマッピング()に関する情報を提供しRequestMappingInfoます。

@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;

@PostConstruct
public void init() {
    Map<RequestMappingInfo, HandlerMethod> handlerMethods =
                              this.requestMappingHandlerMapping.getHandlerMethods();

    for(Entry<RequestMappingInfo, HandlerMethod> item : handlerMethods.entrySet()) {
        RequestMappingInfo mapping = item.getKey();
        HandlerMethod method = item.getValue();

        for (String urlPattern : mapping.getPatternsCondition().getPatterns()) {
            System.out.println(
                 method.getBeanType().getName() + "#" + method.getMethod().getName() +
                 " <-- " + urlPattern);

            if (urlPattern.equals("some specific url")) {
               //add to list of matching METHODS
            }
        }
    }       
}

このBeanは、コントローラーが定義されているSpringコンテキストで定義されていることが重要です。

于 2012-12-25T21:05:51.980 に答える
5

を呼び出すことにより、マップされたコントローラーを取得しますHandlerMapping.getHandler(HTTPServletRequest).getHandler()。HandlerMappingインスタンスは、IoCによって取得できます。HTTPServletRequestがない場合は、MockHttpServletRequestを使用してリクエストを作成できます。

@Autowired
private HandlerMapping mapping;

public Object getController(String uri) {
    MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
    // configure your request to some mapping
    HandlerExecutionChain chain = mapping.getHandler(request);
    return chain.getHandler();
}

申し訳ありませんが、URLにすべてのコントローラーが必要であることを読みました。これにより、完全に一致するコントローラーが1つだけ生成されます。それは明らかにあなたが必要としないことを望んでいません。

于 2012-12-28T13:16:04.867 に答える
3

ListableBeanFactoryインターフェースを使用して、すべてのBean名を取得してみることができます。

private @Autowired ListableBeanFactory beanFactory;

public void doStuff() {
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
        if (beanName.startsWith("env")) { // or whatever check you want to do
            Object bean = beanFactory.getBean(beanName)
            // .. do something with it
        }
    }
}

ListableBeanFactoryのドキュメントはこちらをご覧ください。このインターフェースは、getBeansOfType()、getBeanDefinitionCount()などのいくつかのメソッドを提供します。

このアプローチで@Controller注釈付きBeanがリストされていない場合は、このページにアクセスして、その方法を確認してください。

于 2012-12-28T12:21:17.093 に答える
0

ディスパッチャサーブレットでRequestMappingHandlerMappingのエントリを作成する必要があります

<bean name="requestHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="useTrailingSlashMatch" value="true"></property>
    </bean>

ディスパッチャサーブレットはこのマッピングを調べて、アプリケーションでBeanRequestMappingHandlerMappingをインスタンス化します。

これで、どのコントローラー/クラスでも使用できます

@Autowired
private HandlerMapping mapping;

正常に動作するはずです。

注:Beanの追加には注意が必要です。ディスパッチャーサーボレット(大きなアプリケーションの場合)にこのBeanが含まれていると、noUniqueBean例外が発生し、アプリケーションが起動しません。

于 2016-07-07T09:52:22.017 に答える