Learning Content
The spring framework is powerful and has been subscribed to by a message from within the app. We don't even need to include anything in the configuration file (code). We will learn how to publish and subscribe to a message in a spring application to define events
Events need to inherit spring's applicationevent. After the event is published, the broker (Spring framework) is sent to subscribers to the subscription. If you subscribe to such an event, the associated subclass event is also heard. Here is an example: Topevent <-centerevent;topevent <-middleevent <-.
public class Topevent extends applicationevent{
private static final long serialversionuid = 1L;
Public Topevent (String event) {
super (event);
}
}
public class Centerevent extends topevent{
private static final long serialversionuid = 1L;
Public Centerevent (String event) {
super (event);
}
}
public class Middleevent extends Topevent {
...
}
public class Bottomevent extends middleevent{...
}
If we subscribe to a topevent, we'll hear topevent,centerevent,middleevent and bottomevent; If you subscribe to Middleevent, Will be heard middleevent and bottomevent, if subscribed to centerevent, then monitor centerevent. It can be said that spring is based on type matching to determine subscribers, while the attributes sent to subscribers start with the most matching send, but this order is meaningless based on the loosely coupled development features of the Publish/subscribe model.
Let's look at a small example of the user login event and the logout event, both of which are part of the authentication event.
In this small example, we'll focus on a little tip, Authenticationevent is the base class for Loginevent and Logoutevent, but we don't want to be published as an event, with abstract, That is, the Publisher must specifically give the login or logout event. Public
abstract class Authenticationevent extends applicationevent{
private static final long Serialversionuid = 1L;
Public authenticationevent (Object source) {
super (source);
}
}
public class Loginevent extends authenticationevent{
private static final long serialversionuid = 1L;
Public loginevent (String username) {
super (username);
}
}
public class Logoutevent extends authenticationevent{...
}
Publishing Events
@Controller public
class HomeController {
private static final Logger log = Logmanager.getlogger ();
1 "Inject spring's publisher
@Inject applicationeventpublisher Publisher;
@RequestMapping ("") Public
String Login (httpservletrequest request) {
Log.info ("Publish login Event");
2 "Publish Event
This.publisher.publishEvent (New Loginevent (REQUEST.GETREMOTEADDR ()));
return "Login";
@RequestMapping ("/logout") public
String Logout (httpservletrequest request) {
Log.info ("Publish Logout Event ");
2 "Publish Event
This.publisher.publishEvent (New Logoutevent (REQUEST.GETREMOTEADDR ()));
Return "logout";
}
Subscribe to Events
Subscribe to an event
Subscribing to an event is simple, as long as you implement applicationlistener<xxxevent>, because we're using Spring's publish/subscribe, we have to be in the spring framework, the class needs to add @component, here, Use the @service
@Service public
class Authenticationinterestedparty implements applicationlistener< authenticationevent>{
private static final Logger log = Logmanager.getlogger ();
@Override public
void Onapplicationevent (Authenticationevent event) {
log.info ("Authentication event for IP Address {}. ", Event.getsource ());
}
}
Similarly, we can use the public class Logininterestedparty implements applicationlistener<loginevent>{...} Monitor Loginevent. Let's look at the log output:
16:18:21.479 [http-nio-8080-exec-3] [DEBUG] (Spring) Dispatcherservlet-dispatcherservlet with Name ' Springwebdispatcher ' processing get request for [/chapter18/] 16:18:21.479 [http-nio-8080-exec-3] [DEBUG] (Spring) Requestmappinghandlermapping-looking up handler to path/16:18:21.479 [http-nio-8080-exec-3] [DEBUG] (Spring) R Equestmappinghandlermapping-returning handler method [public java.lang.String Cn.wei.chapter18.site.publish_ Subscribe. Homecontroller.login (javax.servlet.http.HttpServletRequest)] 16:18:21.479 [http-nio-8080-exec-3] [DEBUG] (Spring) Defaultlistablebeanfactory-returning cached instance of singleton Bean ' HomeController ' 16:18:21.479 [ HTTP-NIO-8080-EXEC-3] [DEBUG] (Spring) dispatcherservlet-last-modified value for [/chapter18/] is:-1 16:18:21.512 [http -NIO-8080-EXEC-3] [INFO] homecontroller:24 login ()-Publish login Event 16:18:21.512 [http-nio-8080-exec-3] [DEBUG] (SPR ing) defaultlistablebeanfactory-returning Cached instance of singleton Bean 'Authenticationinterestedparty ' 16:18:21.512 [http-nio-8080-exec-3] [DEBUG] (Spring) defaultlistablebeanfactory- Returning cached instance of singleton Bean ' logininterestedparty ' 16:18:21.512 [http-nio-8080-exec-3] [INFO] Authentica
Tioninterestedparty:14 onapplicationevent ()-authentication event for IP address 0:0:0:0:0:0:0:1. 16:18:21.512 [http-nio-8080-exec-3] [INFO] logininterestedparty:16 onapplicationevent ()-Login event for IP address 0:0: 0:0:0:0:0:1.
You can see the publishing and subscriber processing and the servlet processing on the same thread. In publish/subscribe mode, the Publisher does not care what the Subscriber does, and if the Subscriber is processed for a long time, it must affect the publisher's normal servlet processing. Therefore, subscribers are better suited to asynchronous processing.
@Service public
class Logoutinterestedparty implements applicationlistener<logoutevent>{
private Static final Logger log = Logmanager.getlogger ();
@Override
@Async public
void Onapplicationevent (Logoutevent event) {
log.info (' Logout event for IP address {}. ", Event.getsource ());
try {
Thread.Sleep (3000);
} catch (Interruptedexception e) {
}
log.info ("Logout done");
}
Output to (raise the output level of spring to info):
16:25:17.440 [http-nio-8080-exec-6] [INFO] authenticationinterestedparty:14 onapplicationevent ()-Authentication Event for IP address 0:0:0:0:0:0:0:1.
16:25:17.519 [task-1] [INFO] logoutinterestedparty:16 onapplicationevent ()-Logout event for IP address 0:0:0:0:0:0:0:1.
16:25:20.521 [task-1] [INFO] logoutinterestedparty:21 onapplicationevent ()-Logout done
Subscribe to multiple Events
In practice, it is possible for a service to order several events, but Java cannot implement an interface multiple times:
public class MyService implements applicationlistener<oneevent>,applicationlistener<twoevent>{}// This is not allowed.
We can use the following methods:
/** * This demonstrates how to subscribe to multiple events in the same class (in a service), using an internal class.
* In the spring framework, an instance is required to be managed as a spring framework, and a @bean identity needs to be added, as we did in the configuration file. * We will use the concrete implementation of Spring Applicationlistener (internal class) as @bean in this tag, into the spring framework, as the @component used in the class as a-*/@Service public class
EventService {private static final Logger Logger = Logmanager.getlogger (); @Bean public applicationlistener<bottomevent> Bottomeventlistener () {return new applicationlistener<b Ottomevent> () {@Async public void Onapplicationevent (Bottomevent event) {Logge
R.info ("Bottom event for {}", Event.getsource ());
};
}; @Bean public applicationlistener<centerevent> Centereventlistener () {return new Applicationlisten
Er<centerevent> () {@Async public void Onapplicationevent (Centerevent event) {
Logger.info ("Center event for {}", Event.getsource ());
};
}; } @Bean PUBlic applicationlistener<middleevent> Middleeventlistener () {return new APPLICATIONLISTENER<MIDDLEEVENT&G t; () {@Async public void Onapplicationevent (Middleevent event) {logger.info ("Midd
Le event for {}. ", Event.getsource ());
};
}; @Bean public applicationlistener<topevent> Topeventlistener () {return new applicationlistener< Topevent> () {@Async public void Onapplicationevent (Topevent event) {Logger.inf
O ("top event for {}", Event.getsource ());
};
}; }
}
RELATED links: My professional Java for WEB applications related articles