1.1 introduction to monitor
What is a web listener? A web listener is a special class in a Servlet that helps developers listen to specific events in the web, such as ServletContext,
Httpsession, creation and destruction of ServletRequest, creation, destruction and modification of variables can be added before and after certain actions to realize monitoring
1.2 example of monitor
There are many usage scenarios of web listener, such as listening to servlet context to initialize some data, listening to http session to obtain the current number of people online and listening to customers
In this section, we mainly learn about Spring Boot through these three actual use scenarios
Use of the monitor in
1.2.1 listening to Servlet context object
Listening servlet context object can be used to initialize data and cache. What do you mean? I take a very common scenario, for example, when a user clicks the homepage of a site,
Generally, some information of the homepage will be displayed, and the information will remain unchanged basically or most of the time, but the information is from the database. If the user's
Click to get data from the database. If the number of users is small, it is acceptable. If the number of users is very large, it is also a big expense for the database
For this kind of homepage data, if most of them are not updated frequently, we can cache them completely. Every time a user clicks, we take them directly from the cache, so that we can
If you are more flexible, you can add a timer to update the homepage cache regularly. It is similar to
CSDN personal blog home page ranking changes the same
Next, we will write a demo for this function. In practice, readers can fully apply this code to realize the relevant logic of their own project. First, write a Service module
To query data from the database
@Service
public class UserService {
User getUser(){
return new User(1, "lwh", 25);
}
}
Then write a listener, implement the applicationlistener < contextrefreshedevent > interface, rewrite the onApplicationEvent method, and
The ContextRefreshedEvent object is passed in. If we want to refresh our preloaded resources when loading or refreshing the application context, we can
To do this by listening to the ContextRefreshedEvent, as follows:
@Component
public class MyServletContextListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// Get the applicationContext context first
ApplicationContext ctx = event.getApplicationContext();
UserService userService = ctx.getBean(UserService.class);
User user = userService.getUser();
// Get the application domain object and put it into the application domain
ServletContext application = ctx.getBean(ServletContext.class);
application.setAttribute("user", user);
}
}
As described in the note, first get the application context through contextRefreshedEvent, and then get it through the application context
The user service bean can get other beans according to the actual business scenario in the project, and then call your own business code to get the corresponding data,
Finally, it is stored in the application domain, so that when the front-end requests the corresponding data, we can directly obtain information from the application domain and reduce the pressure of the database
Next write a Controller to get user information directly from the application domain to test
@Controller
public class ListenerController {
@GetMapping("/listener/user")
@ResponseBody
public User getUser(HttpServletRequest request){
ServletContext application = request.getServletContext();
return (User) application.getAttribute("user");
}
}
// Source code analysis
// Check for listener beans and register them.
// In the Refresh method, this step registers the listener we defined into the container
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// The ContextRefreshedEvent event will be published here, and our custom listener can get it
finishRefresh();
// registerListeners();
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
protected void finishRefresh() {
// Publish the final event.
// Delete other code, and the event will be published in it, and our customized listening method will be called. For details, see the second listener mode
publishEvent(new ContextRefreshedEvent(this));
}
1.2.2 listening to HTTP Session object
There is also a common place for listeners to monitor session object,To get the number of online users,Many developers now have their own websites,Monitor
session To get the current number of users is a very common use scenario,Here's how to use it.
@Component
public class MyHttpSessionListener implements HttpSessionListener {
// Record the number of online users
public Integer count = 0;
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("The user is online");
count++;
HttpSession session = httpSessionEvent.getSession();
session.setMaxInactiveInterval(1);
session.getServletContext().setAttribute("count", count);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("The user is offline");
count--;
httpSessionEvent.getSession().getServletContext().setAttribute("count", count);
}
}
// Let the server remember the original session, that is, record the original sessionId in the browser, and transfer the sessionId to the next time you open it,
// So the server won't be recreated
@GetMapping("/listener/total2")
@ResponseBody
public String getTotalUser(HttpServletRequest request, HttpServletResponse response){
Cookie cookie;
try {
cookie = new Cookie("JSESSIONID", URLEncoder.encode(request.getSession().getId(), "UTF-8"));
cookie.setPath("/");
// Valid for two days
cookie.setMaxAge(48 * 60 * 60);
response.addCookie(cookie);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
return "Current online population: " + count;
}
1.3. Custom listener
In actual projects, we often need to customize some events and listeners to meet business scenarios. For example, in microservice, there will be A scenario: microservice A processes some logic,
Microservice B needs to be informed to process another logic, or microservice A needs to synchronize data to microservice B after processing A logic. This is A very common scenario. At this time,
We can customize events and listeners to monitor. Once an event in microservice A is detected, microservice B will be notified to process the corresponding logic
public class MyEvent extends ApplicationEvent {
private User user;
public MyEvent(Object source, User user) {
super(source);
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
// Get information about the event
User user = event.getUser();
// Handling events, notifying other microservices or handling other logic in the actual project, etc
System.out.println("User name: " + user.getName());
System.out.println("Age:" + user.getAge());
}
}
@Service
public class UserService {
@Resource
private ApplicationContext ctx;
User publishEvent(){
User user = new User(1, "lwh", 25);
// Release events
MyEvent myEvent = new MyEvent(this, user);
ctx.publishEvent(myEvent);
return user;
}
}