官术网_书友最值得收藏!

Ordered events

This basically orders the observers using the @Priority annotation. This feature can be made use of when there are multiple observer methods and you need to control which ones are called first and which ones are called later:

  • The lowest value would be the first observer method that gets called
  • The highest value would be called last
  • If there's no priority specified then this event will be considered mid-range priority
  • For observer methods with the same priority, the ordering is undefined
  • No priority is applicable for asynchronous events, since they're not sequential

The usage of the ordered event is shown here:

public void observer1(@Observes @Priority(1) Payload event) { }
public void observer2 (@Observes @Priority(2) Payload event) { }

Given the behavior of ordered events using @Priority, along with the mutable state of the payload, one could utilize this feature for certain use cases. Consider a fairly common scenario in which the system should lock the user account based on the number of failed login attempts. Additionally, send out a notification to the user, such as an SMS, if the account gets locked in the process. In this case, we could define two ordered observers for this type of event, with the first observer checking for failed attempts and setting the lock status on the payload object. The second observer would then be able to see the changes made to the payload by the first observer and thus, based on this change in status, it would send the notification. Let us see, how this can be tackled in the sample code explained next.

A login service will raise a LoginEvent containing a user's ID and attempt count. Take a look at the LoginEvent code:

public class LoginEvent {
private final Integer attemptsMade;
private final String userId;
private boolean lockAccount = false;

public LoginEvent(Integer count, String userId) {
this.attemptsMade = count;
this.userId = userId;
}
...
}

The relevant code snippet for the AccountService, a class responsible for signing in the user and raising an event, is shown here:

@Inject private Event<LoginEvent> event;

/* A login method on this class, raises the event for failed login attempts using below line. */
event.fire(new LoginEvent(attemptsMadeCount, byUserId ));

The first observer is responsible for checking and locking the account based on attempts made:

public class MonitorAccountAccess {
public static final Integer MAX_ATTEMPTS = 3;

public void lockForFailedAttempts(
@Observes @Priority(1) LoginEvent event) {
if(event.getAttemptsMade() >= MAX_ATTEMPTS) {
event.setLockAccount(true);
//do more work to push status in database
}
}
}

The second observer is responsible for sending an SMS when an account gets locked. This code relies on the lock account status update being changed in the MonitorAccountAccess code block:

public class AccountLockNotification {

public void sendSmsOnAccountLock(@Observes @Priority(2) LoginEvent event) {
if(event.isLockAccount() == false) return;
sendAccountLockSms(event.getUserId());
}
}

When the event is fired synchronously from the AccountService code, MonitorAccountAccess will be called first, as it has @Priority(1). Later, the AccountLockNotification code gets called, along with @Priority(2) and the updated LoginEvent object.

主站蜘蛛池模板: 河西区| 三亚市| 黄大仙区| 冕宁县| 拉萨市| 师宗县| 潮州市| 高碑店市| 澳门| 中山市| 阳江市| 天台县| 江华| 靖边县| 建阳市| 冀州市| 福泉市| 宝应县| 邛崃市| 木兰县| 安阳县| 高青县| 洛南县| 宜兰县| 鞍山市| 荆门市| 义马市| 黄石市| 疏附县| 余姚市| 惠安县| 肥城市| 建始县| 兴安县| 南华县| 绥德县| 鄢陵县| 高唐县| 丰城市| 连江县| 五原县|