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

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.

主站蜘蛛池模板: 黄大仙区| 民丰县| 崇州市| 乃东县| 苍山县| 肃宁县| 长葛市| 姚安县| 楚雄市| 廊坊市| 利川市| 阿勒泰市| 高淳县| 六枝特区| 元谋县| 曲松县| 双桥区| 泸州市| 博乐市| 两当县| 凌源市| 蕲春县| 中方县| 鹤山市| 镇江市| 化德县| 搜索| 红原县| 桃源县| 商丘市| 本溪市| 格尔木市| 绵阳市| 偏关县| 沙田区| 原阳县| 新巴尔虎左旗| 天峻县| 南京市| 东安县| 曲沃县|