Недавно я посмотрел на исходный код весны и внезапно задавался вопросом, как Spring началась без конфигурации Web.xml. Учитывая ограниченную способность и в первый раз, когда я прочитал исходный код и опубликовал блог, пожалуйста, простите меня, если я не знаю, что делать ~
IDE, которую я использую, - это INTELLIJ Idea, которую проще читать исходный код, чем MyEclipse, и мне очень нравится на черном фоне. Затем проект запускается под плагином Maven Tomcat7. Весенняя версия 4.3.2.
Если вы написали весеннюю сеть с конфигурацией чистой аннотации, вы должны знать, что вам необходимо унаследовать класс инициализации для загрузки бобов, а затем наши индивидуальные функции и бобы будут загружены из этого класса. Ниже приведен один из моих вебинтиализаторов
@Order (1) public class webmvcinit extends AbstractAnnotationConfigDispatcherServletinitialize {Protected Class <?> [] GetRootConfigClasses () {return New Class [] {rootConfig.class, webseCurityConfig.class}; } защищенный класс <?> [] getServletConfigClasses () {return New Class [] {webConfig.class}; } защищенная string [] getServletmappings () {return new String [] {"/"}; } @Override Protected Filter [] getServletFilters () {return new Filter [] {new hiddenhttpmethodfilter ()}; }}Во -первых, посмотрите на структуру класса AbstractAnnotationConfigDispatcherServletinitializer. Это также UML -функция идеи. Щелкните правой кнопкой мыши диаграммы-> показать диаграммы в классе.
Затем мы напрямую нажимаем на AbstractAnnotationConfigDispatcherServletinitializer. Вы можете видеть, что этот класс очень прост, только с четырьмя методами. Затем мы обращаем внимание на CreaterootApplicationContext ()
@Override Protected WebApplicationContext CreaterOutApplicationContext () {class <?> [] Configclass = getRootConfigClasses (); if (! objectutils.isempty (configclasses)) {annotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext (); RootAppContext.register (configclasses); вернуть RootAppContext; } else {return null; }}Этот метод примерно означает получить корневые классы, отправленные пользователем (программистом), а затем зарегистрировать бобы. Это не то, что нас беспокоит, но этот метод должен быть выполнен после запуска, поэтому мы можем посмотреть на этот метод
В соответствии с идеей, Ctrl+G может найти метод или класс для вызова, а затем установить диапазон поиска для проекта и библиотеки
Мы обнаружили, что метод RegisterContextLoaderListener (ServletContext ServletContext) в AbstractContextLoadErinitializer вызывает CreaterOutApplicationContext () подкласса, чтобы получить веб -сайт -cplicationContext и продолжать найти вызывающего абонента метода RegisterContextListener (ServletContext -Context). В результате обнаружено, что в этом классе есть OnStartup (ServletContext ServletContext). Класс AbstractContextLoadErinitializer размещен ниже.
Public Abstract Class AbstractContextLoadErinitializeлизатор реализует WebApplicationInitialize { / ** Logger, доступный для подклассов* / Защищенный окончательный журнал журнала = logfactory.getLog (getClass ()); @Override public void OnStartUp (ServletContext ServletContext) Throws ServletException {RegisterContextLoaderListener (ServletContext); } /*** Зарегистрируйте {@link contectlesloaderListener} против данного контекста сервлета. * {@Code ContextLoaderListener} инициализируется с возвращенным контекстом приложения * из метода шаблона {@link #createrootapplicationcontext ()}. * @param ServletContext Контекст сервлета для регистрации прослушивателя против */ Protected void RegistertextListerListener (ServletContext ServletContext) {WebApplicationContext RootAppContext = createRootApplicationContext (); if (RootAppContext! = null) {ContextLoaderListener alluster = new ContextLoaderListener (RootAppContext); Слушатель.setContextInitializers (getRootApplicationContextInitializers ()); ServletContext.AddListener (слушатель); } else {logger.debug ("no contectflegloadlistener, как" + "createrootApplicationContext () не вернул контекст приложения"); }} /** * Создать контекст приложения «<strong> root < /strong>», который будет предоставлен для * {@Code ContextLoaderLister}. * <p> Возвращенный контекст делегируется * {@link contextLoaderListener#contextLoaderListener (webApplicationContext)} и будет * будет установлен как родительский контекст для любого {@Code DispatcherServlet} Contexts. Таким образом, он обычно содержит сервисы среднего уровня, источники данных и т. Д. * @return Корневой приложение контекст, или {@code null}, если корневой контекст не является * желаемой * @see org.springframework.web.servlet.support.abstractdispatcherservelicalizer */ protected rethable webapplicationcontextextextextexteplictictectrectrectectcherservlectializez /** * Укажите инициализаторы контекста приложения, которые будут применены к контексту корневого приложения *, с которым создается {@code contectlectloaderListener}. * @since 4.2 * @see #createrootapplicationcontext () * @see contextlisterlistener #setContextInitializers */ protected ApplicationContextInitialize <?> [] getRootApplicationContextInitializers () {return null; }}Обратите внимание, что мы пропустили класс AbstractDispatcherServletinitializer Abstract (см. Диаграмму UML). Этот класс в основном настраивает DispatcherServlet, который является реализацией Spring MVC и других функций.
Тогда кто загрузит AbstractContextLoadErinitializeлизатор? WebApplicationInitializer уже интерфейс, и не будет абстрактного класса, чтобы назвать его. Поэтому я попытался искать интерфейс WebApplicationInitializer. Поскольку крупные проекты, такие как Spring, определенно ориентированы на интерфейс, вызов обычно записывается в интерфейс. Затем мы обнаружили класс SpringservletContainerInitializer, который реализует интерфейс ServletContainerInitializer. Этот класс, вероятно, означает запуск всех WebPplicationInitializers. Можно сказать, что этот класс очень близок к нашей цели. Ниже приведен Springservletcontainerinitializer
@Handlestypes (webapplicationInitialization.class) открытый класс SpringservletContainerInitializer реализует ServletContainerInitializer {@Override public void onStartUp (set <? >> WebAppinitializerClass, ServletContext -Context) ThrowSception {list <Webapplication> New LinkedList <WebApplicationInitializer> (); if (webappinitializerclass! = null) {for (class <?> waiclass: webappinitializerclass) {// быть оборонительным: некоторые контейнеры сервлета предоставляют нам недопустимые классы, // Независимо от того, что говорит @handlestypes ... if (! waiclass.isinterface () &&! WebapplicationInitialize.class.isassignablefrom (waiclass)) {try {initializers.add ((webapplicationInitialize) waiclass.newinstance ()); } catch (Throwable ex) {Throw New ServletException («Не удалось создать экземпляр webApplicationInitializer class», Ex); }}}}} if (initializers.isempty ()) {servletContext.log ("Нет Spring WebPplicationInitializers, обнаруженные на ClassPath"); возвращаться; } servletContext.log (initializers.size () + "Spring WebPplicationInitializers, обнаруженные на классе"); AnnotationAwareRoderComparator.sort (инициализаторы); для (webapplicationInitializer initializer: initializers) {initializer.onstartup (ServletContext); }}}В последней Foreach запустите все WebPplicationInitializers. Итак, вопрос в том, кто начнет SpringservletContainerInitializer? Весна определенно не сможет запустить его сама по себе.
В веб -среде есть только веб -контейнеры. Мы можем сделать точку останова в одном из вышеперечисленных мест, а затем отладить ее (на самом деле, мы можем полностью отладить = = = на протяжении всего процесса, который является точным и быстрым, но в этом не хватает значения поиска, и пейзаж вдоль дороги довольно хорош)
Вы можете увидеть начальный метод класса StandardContext в рамках пакета org.apache.catalina.core. Это уже в сфере Tomcat, поэтому наша цель была достигнута. Обратите внимание, что интерфейс ServletContainerInitializer не находится под пакетом Spring, но является Javax.servlet
Я предполагаю, что Tomcat использует интерфейс ServletContainerInitializer of Javax.Servlet, чтобы найти классы, которые реализуют этот интерфейс в контейнере, затем назовут их oNSARTUP, а затем SpringservletContainerInitializer может запустить все WebApplicationInitializers, которые содержит Webinitializer, который мы написали сами. Кроме того, Spring Security также настроена с аннотацией для реализации WebApplicationInitializer, поэтому пружина очень расширяется. Давайте посмотрим на исходный код Tomcat в ближайшие несколько дней, чтобы понять механизм Tomcat.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.