Symfony2 source code analysis-START process 2, symfony2 source code

Source: Internet
Author: User

Symfony2 source code analysis-START process 2, symfony2 source code

The previous article analyzed the source code of the Symfony2 framework and explored how Symfony2 completed the first half of a request. The first half can be understood as preparing for request processing by the Symfony2 framework, including container generation, cache, bundls initialization, and other column preparation work (Symfony2 source code analysis-startup process 1 ). This article describes how Symfony2 generates a Response object based on the request data and returns Response data to the client.

Before analysis, you need to understand the Symfony2 event-driven mechanism: Symfony2 event-driven.

To put it bluntly, the workflow of the Symfony2 request is actually completed by the event driver of the Symfony2 kernel. The following is the kernel event defined by the Symfony2 framework:

Final class KernelEvents {/*** The REQUEST event occurs at the very beginning of request * dispatching ** This event allows you to create a response for a request before any * other code in framework is executed. the event listener method * has es a Symfony \ Component \ HttpKernel \ Event \ GetResponseEvent * instance. ** @ var string ** @ api */const REQUEST = 'kernel. request ';/*** The EXCEPTION event occurs when an uncaught exception appears ** This event allows you to create a response for a thrown exception or * to modify the thrown exception. the event listener method has es * a Symfony \ Component \ HttpKernel \ Event \ GetResponseForExceptionEvent * instance. ** @ var string ** @ api */const EXCEPTION = 'kernel. exception '; /*** The VIEW event occurs when the return value of a controller * is not a Response instance ** This event allows you to create a response for the return value of the * controller. the event listener method has es a * Symfony \ Component \ HttpKernel \ Event \ GetResponseForControllerResultEvent * instance. ** @ var string ** @ api */const VIEW = 'kernel. view';/*** The CONTROLLER event occurs once a controller was found for * handling a request ** This event allows you to change the controller that will handle the * request. the event listener method has es a * Symfony \ Component \ HttpKernel \ Event \ FilterControllerEvent instance. ** @ var string ** @ api */const CONTROLLER = 'kernel. controller ';/*** The RESPONSE event occurs once a response was created for * replying to a request ** This event allows you to modify or replace the response that will be * replied. the event listener method has es a * Symfony \ Component \ HttpKernel \ Event \ FilterResponseEvent instance. ** @ var string ** @ api */const RESPONSE = 'kernel. response';/*** The TERMINATE event occurs once a response was sent ** This event allows you to run expensive post-response jobs. * The event listener method has es a * Symfony \ Component \ HttpKernel \ Event \ PostResponseEvent instance. ** @ var string */const TERMINATE = 'kernel. terminate';/*** The FINISH_REQUEST event occurs when a response was generated for a request. ** This event allows you to reset the global and environmental state of * the application, when it was changed during the request. ** @ var string */const FINISH_REQUEST = 'kernel. finish_request ';}View Code

We can write an event listener to listen to the corresponding kernel events. When Symfony2 triggers this event, the corresponding event listener will execute. Monitor and wake up the image description, just like, You (event listener) participate in the sports meeting, go to the Conference (Symfony2) Registration (listener) to participate in the 50-meter sprint (event ), when the 50-meter sprint starts (the event is triggered), you can run it (listener execution is actually an execution function. It depends on your needs to complete the function ), teenagers.

Most of the work of the Symfony2 kernel event processing process is in the HttpKernel: handleRaw method:

1 private function handleRaw (Request $ request, $ type = self: MASTER_REQUEST) 2 {3 $ this-> requestStack-> push ($ request ); 4 5 // request 6 // initialize the event. The event object is passed to the listener. Therefore, the event is a carrier of information, and the event memory contains the data interested in the listener. 7 $ event = new GetResponseEvent ($ this, $ request, $ type); 8 // trigger the kernel. request event. For more information, see EventDispatcher: Implementation of the dispatch method. 9 // here We Need To Know That dispatcher passes $ event to all the listening kernel. request event listener, which will be executed. 10 // kernel. before the request event occurs in the controller execution, we can complete the route parsing in this step and provide data preparation for the controller execution. 11 // in this process, we can directly generate the Response object, if the data is output to the client, the controller will not be executed. 12 $ this-> dispatcher-> dispatch (KernelEvents: REQUEST, $ event); 13 14 // if we have. the request event generates a Response object (Response data), so the kernel is skipped. controller, kernel. view event, 15 // controller will also be skipped and the kernel will be executed directly. response event. 16 if ($ event-> hasResponse () {17 return $ this-> filterResponse ($ event-> getResponse (), $ request, $ type ); 18} 19 20 // load controller21 // return an object, array, or string based on the routing rules. If $ controller is an array, $ controller [0] stores the controller object to be executed, and 22 // $ controller [0] stores the method to be executed by the controller object, that is, action, the method parameters are not saved in the $ controller array; 23 // If $ controller is an object, the _ invoke method is implemented for this object; 24 // If $ controller is a string, then $ controller is the name of the function to be run. 25 // figure 2 shows a var_dump example of $ controller 26 if (false ===$ controller = $ this-> resolver-> getController ($ request )) {27 throw new NotFoundHttpException (sprintf ('unable to find the controller for path "% s ". maybe you forgot to add the matching route in your routing configuration? ', $ Request-> getPathInfo (); 28} 29 30 $ event = new FilterControllerEvent ($ this, $ controller, $ request, $ type ); 31 // trigger the kernel. controller event, which occurs before the controller is executed. We can modify the controller by listening to this event before the controller executes, 32 // or complete some actions. 33 $ this-> dispatcher-> dispatch (KernelEvents: CONTROLLER, $ event); 34 $ controller = $ event-> getController (); 35 36 // controller arguments37 // obtain the parameters of the controller method from the request object 38 $ arguments = $ this-> resolver-> getArguments ($ request, $ controller ); 39 40 // call controller41 // execute controller42 $ response = call_user_func_array ($ controller, $ arguments); 43 44 // view45 // If $ response is not a Response object, then kernel. view event will Triggered. The Listener that listens to the kernel. view event generates a response object using the $ Response value. 46 if (! $ Response instanceof Response) {47 $ event = new GetResponseForControllerResultEvent ($ this, $ request, $ type, $ response); 48 $ this-> dispatcher-> dispatch (KernelEvents :: VIEW, $ event); 49 50 if ($ event-> hasResponse () {51 $ response = $ event-> getResponse (); 52} 53 54 if (! $ Response instanceof Response) {55 $ msg = sprintf ('the controller must return a response (% s given ). ', $ this-> varToString ($ response); 56 57 // the user may have forgotten to return something58 if (null ===$ response) {59 $ msg. = 'Did you forget to add a return statement somewhere in your controller? '; 60} 61 throw new \ LogicException ($ msg); 62} 63} 64 65 // trigger the kernel. response event. Before outputting a Response object to the client, we can modify the Response object, such as modifying the response header, setting the cache, and compressing the output data. 67 68 // then the kernel. finish_request event is triggered, and the current request pops up from the request stack. The current request is complete. 69 return $ this-> filterResponse ($ response, $ request, $ type); 70 71 // never forget. After filterResponse is executed, the last step of the Symfony2 kernel event processing process is in app_dev.php [app. php] last line, 72 // $ kernel-> terminate ($ request, $ response); this method triggers kernel. the terminate event. At this time, Symfony2 has responded to the client's request, and 73 // output the Response object to the client. The listener for listening to the kernel. terminate event is mainly used to perform some time-consuming operations. The operation result does not need to be returned to 74 // client, such as sending emails or compressing images. 75 // here, the whole process of Symfony2 is finished. 76}
HttpKernel: filterResponse method and HttpKernel: finishRequest method:
1 private function filterResponse (Response $ response, Request $ request, $ type) 2 {3 $ event = new FilterResponseEvent ($ this, $ request, $ type, $ response ); 4 5 $ this-> dispatcher-> dispatch (KernelEvents: RESPONSE, $ event); 6 7 $ this-> finishRequest ($ request, $ type ); 8 9 return $ event-> getResponse (); 10} 11 12/** 13 * Publishes the finish request event, then pop the request from the stack.14 * 15 * Note that the order of the operations is important here, otherwise16 * operations such as {@ link RequestStack: getParentRequest ()} can lead to17 * weird results.18 * 19 * @ param Request $ request20 * @ param int $ type21 */22 private function finishRequest (Request $ request, $ type) 23 {24 $ this-> dispatcher-> dispatch (KernelEvents: FINISH_REQUEST, new FinishRequestEvent ($ this, $ request, $ type )); 25 $ this-> requestStack-> pop (); 26}View Code

Figure 2

Core code of the event distribution mechanism in the Symfony2 framework:

1 public function dispatch ($ eventName, Event $ event = null) 2 {3 if (null ===$ event) {4 $ event = new Event (); 5} 6 7 $ event-> setDispatcher ($ this); 8 $ event-> setName ($ eventName); 9 10 if (! Isset ($ this-> listeners [$ eventName]) {11 return $ event; 12} 13 14 // $ eventName: KernelEvents: REQUEST, KernelEvents :: CONTROLLER, KernelEvents: VIEW, KernelEvents: RESPONSE, KernelEvents :: TERMINATE and so on 15 // getListeners returns all listeners listening for the $ eventName event 16 $ this-> doDispatch ($ this-> getListeners ($ eventName), $ eventName, $ event ); 17 18 return $ event; 19} 20 21 protected function doDispatch ($ listeners, $ eventName, Event $ eve Nt) 22 {23 // The listener executes 24 foreach ($ listeners as $ listener) {25 call_user_func ($ listener, $ event, $ eventName, $ this ); 26 // if one of the listeners sets the propagationStopped attribute of $ event to true, the $ eventName event is terminated, 27 // The event will not be passed to the listener that has not been executed in $ listeners. 28 if ($ event-> isPropagationStopped () {29 break; 30} 31} 32}

 


Is there any book specific to the Linux kernel startup process? For details (it is best to be specific to the actual Code), it is best to look at the kernel after 26

I personally feel that Mr. Mao's book Linux kernel scenario analysis is very thorough, and the explanation of the entire Linux kernel is very good. specific to the startup process, this startup process is very extensive. You only need to know the overall startup process. For other details, please refer to the kernel source code. Therefore, we recommend that you read this blog to learn about the general startup process. For details, see the Linux kernel scenario analysis.

Android 21 source code analysis by pressing the power button dialog box

1. This dialog is controlled by PhoneWindowManager. In the interceptKeyTq method of PhoneWindowManager, the code is this line.

MHandler. postDelayed (mPowerLongPress, ViewConfiguration. getGlobalActionKeyTimeout ());

MProwerLongPress is a Runnable that calls the showDialog method in GlobalActions during execution. Therefore, this dialog is managed by GlobalActions, and PowerDialog is in a previous version and is now obsolete.

2. You can add the mSilentModeToggle action onToggle method to the createDialog method in GlobalActions.

MAudioManager. setVibrateSetting (AudioManager. VIBRATE_TYPE_RINGER, on? AudioManager. VIBRATE_SETTING_ON: AudioManager. VIBRATE_SETTING_OFF );

This sentence, like the handle of the ringtone, should be okay, but it cannot be determined even if you do not try it.

Hope to help you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.