2015-06-05 8 views
13

मूल रूप से मैं अपने आवेदन को 2 भागों में विभाजित करना चाहता हूं। प्रत्येक भाग में इसकी अपनी सुरक्षा सामग्री होती है और @Controller एस है। दोनों भागों से सुलभ होना चाहिए।एकाधिक डिस्पैचर सर्विलेट के साथ स्प्रिंग बूट, प्रत्येक के पास अपने स्वयं के @ नियंत्रक

तो मैंने सोचा, मुझे 2 DispatcherServlet मिलना चाहिए। एक /admin/* और दूसरा सब कुछ सुन रहा है (/)। उनमें से प्रत्येक का अपना AnnotationConfigWebApplicationContext होगा, इसलिए मेरे पास @Controller एस के लिए अलग घटक स्कैन हो सकता है।

और क्योंकि वसंत बूट बॉक्स से बाहर / पर एक DispatcherServlet सुनने प्रदान करता है, मैंने सोचा, मैं तो बस एक दूसरे के जोड़ सकते हैं:

@Configuration 
public class MyConfig { 
    @Bean(name="myDS") 
    public DispatcherServlet myDS(ApplicationContext applicationContext) { 
     AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext(); 
     webContext.setParent(applicationContext); 
     webContext.register(MyConfig2.class); 
     // webContext.refresh(); 
     return new DispatcherServlet(webContext); 
    } 

    @Bean 
    public ServletRegistrationBean mySRB(@Qualifier("myDS") DispatcherServlet dispatcherServlet) { 
     ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet); 
     servletRegistrationBean.addUrlMappings("/admin/*"); 
     servletRegistrationBean.setName("adminServlet"); 
     return servletRegistrationBean; 
    } 
} 

MyConfig2 वर्ग, केवल @Configuration और @ComponentScan। उसी पैकेज में @Controller है।

एप्लिकेशन शुरू करते समय, मैं देख सकता हूं कि दूसरा सर्वलेट मानचित्रण पंजीकृत हो रहा है, लेकिन @Controller नहीं है। इसके अतिरिक्त अब मैं सभी@Controllers/और/admin से अब तक पहुंच सकता हूं।


कोई विचार यह है कि मैं यह कैसे काम कर सकता हूं?

उत्तर

26

मुझे यह किसी भी तरह से काम मिल गया!

test.foo. 
     FooConfig.java 
     FooController.java 
test.bar. 
     BarConfig.java 
     BarController.java 
test.app. 
     Application.java 
     MyService.java 
src/main/resources/application.properties 

Application.java:

@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class) 
public class Application { 
    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class, args); 
    } 
    @Bean 
    public ServletRegistrationBean foo() { 
     DispatcherServlet dispatcherServlet = new DispatcherServlet(); 
     AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); 
     applicationContext.register(FooConfig.class); 
     dispatcherServlet.setApplicationContext(applicationContext); 
     ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/foo/*"); 
     servletRegistrationBean.setName("foo"); 
     return servletRegistrationBean; 
    } 
    @Bean 
    public ServletRegistrationBean bar() { 
     DispatcherServlet dispatcherServlet = new DispatcherServlet(); 
     AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); 
     applicationContext.register(BarConfig.class); 
     dispatcherServlet.setApplicationContext(applicationContext); 
     ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/bar/*"); 
     servletRegistrationBean.setName("bar"); 
     return servletRegistrationBean; 
    } 
} 
  • exclude अपनी ही DispatcherServlet/ साथ मानचित्रण बनाने से वसंत बूट को रोकने करता

    यहाँ मेरी पैकेज लेआउट है। यदि आप उस मैपिंग या खुद को परिभाषित करना चाहते हैं, तो आप उस पंक्ति को हटा सकते हैं।

  • यदि आप अपने Servlets को एप्लिकेशन प्रारंभ पर प्रारंभ करना चाहते हैं तो आप servletRegistrationBean.setLoadOnStartup(1) जोड़ सकते हैं। अन्यथा वह उस सर्वलेट के पहले अनुरोध की प्रतीक्षा करेगा।
  • servletRegistrationBean.setName(...) सेट करना महत्वपूर्ण है, अन्यथा servlets एक दूसरे को ओवरराइड करेंगे।

FooConfig.java & BarConfig.java:

@Configuration @ComponentScan @EnableWebMvc 
public class FooConfig { } 
  • @EnableWebMvc घटक स्कैन सक्षम हो जाएगा। इसके बिना, यह @Controller कक्षा नहीं मिलेगा।

नियंत्रक और सेवा कोड महत्वपूर्ण नहीं है। आपको बस यह जानना है कि अगर FooController के अंदर है, तो अनुरोध GET /foo/foo होना चाहिए क्योंकि सर्वलेट का यूआरएल मैपिंग /foo/* है।यह क्योंकि सर्वलेट यूआरएल मानचित्रण अपने रास्ते के अंत में एक / जरूरत यूआरएल GET /foo कॉल करने के लिए संभव नहीं है (दूसरे शब्दों में: GET /foo/ मानचित्रण के साथ एक सर्वलेट के लिए दिखेगा!), हालांकि @RequestMapping("")GET /foo/ के माध्यम से बुलाया जाना चाहिए। नियंत्रकों नहीं एक दूसरे को, देख सकते हैं, हालांकि यह है: और निश्चित रूप से यह सर्वलेट मानचित्रण के रूप में /foo या /foo* उपयोग करने के लिए

स्कोप (या मैं सिर्फ इतना है कि के लिए सही सेटिंग्स नहीं मिला) संभव नहीं था@Autowired उन्हें एक-दूसरे में संभव नहीं है। इसके अलावा सेवा @Autowired नियंत्रकों में से कोई भी नहीं हो सकती है। लेकिन नियंत्रक @Autowired सेवा कर सकते हैं।

हालांकि यह एक शास्त्रीय माता-पिता बाल संदर्भ पदानुक्रम है।

केवल "खराब" बात यह है कि हमें @EnableMvcConfig की आवश्यकता है और संदर्भ में स्प्रिंग बूट से स्वत: कॉन्फ़िगर किया गया चीनी प्राप्त नहीं करें। मूल संदर्भ ऑटो कॉन्फ़िगर किया जा रहा है। मैंने application.properties के भीतर कुछ डेटाबेस सामान डाला और MyService के अंदर एक क्वेरी की जो FooController द्वारा कॉल किया गया और यह बेकार ढंग से काम करता था! :)

मुझे आशा है कि इससे कुछ लोगों की मदद मिल सकती है!

+0

उत्तर के लिए धन्यवाद। वास्तव में मदद करता है। मुझे दूर करने के लिए एक और चुनौती है। मैं/foo endpoints + प्राधिकृत (डीबी आधारित) को प्रमाणित कैसे कर सकता हूं लेकिन केवल/बार एंडपॉइंट्स को प्रमाणित करता हूं? मेरे पास यहां से एक विन्यास है [0]। http://stackoverflow.com/questions/36909226/how-to-configure-waffle-in-spring-using-java-configuration – JHS

+0

धन्यवाद बेंजामिन, मैं एक ही समस्या से जूझ रहा था और पाया कि @EnableMvcConfig को आपके उत्तर पढ़ने के बाद आवश्यक है । – jatanp

+0

उस पूरी व्याख्या के लिए धन्यवाद! इससे मुझे दो अलग-अलग समस्याओं को हल करने में मदद मिली। मेरा मतलब है कि "यह काम करता है:" के साथ स्वयं जवाब देने के लिए आम है: प्लस कोड स्पष्टीकरण के बिना बिट्स ... – sjngm

संबंधित मुद्दे