目录
利用Spring InitializingBean自动注入Handler
在各种高效的编程框架中都有Handler身影,将一类业务通过Handler统一输出可以简化业务编程。比如:业务编号、业务持久化处理、业务异常等处理。
定义Handler类
- public interface ServiceHandler {
-
- ServiceType type();
-
- void execute(String data);
-
- void handleException(String data);
- }
定义类似面向过程编程的需求处理
项目结构:
面向过程服务:
接口:
- /**
- * 面向过程的用户密码修改服务
- */
- public interface UserPwdUpdateService extends ServiceHandler {
- }
实现:
- @Service
- public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
- @Override
- public ServiceType type() {
- return ServiceType.USER_PWD_UPDATE;
- }
-
- @Override
- public void execute(String data) {
- // 1.反序列化数据进行操作
- // 2.执行用户密码持久化操作
- }
-
- @Override
- public void handleException(String data) {
- // 1.反序列化数据进行操作
- // 2.用户密码相关数据回滚
- }
- }
上面是一个很面向过程的处理方式!!!
泛型与面向对象的设计
Handler接口泛型:
- /**
- * 业务处理泛型
- * @param <T>
- */
- public interface ServiceHandler<T> {
-
- ServiceType type();
-
- void execute(T data);
-
- void handleException(T data);
- }
泛型接口定义:
- /**
- * 用户密码修改服务
- */
- public interface UserPwdUpdateService extends ServiceHandler<User> {
- }
业务接口实现:
- @Service
- public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
- @Override
- public ServiceType type() {
- return ServiceType.USER_PWD_UPDATE;
- }
-
- @Override
- public void execute(User user) {
- // 执行用户密码持久化操作
- }
-
- @Override
- public void handleException(User user) {
- // 用户密码相关数据回滚
- }
- }
利用Spring InitializingBean自动注入Handler
- @Component
- public class ServiceTaskManger extends Thread implements InitializingBean {
-
- public static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();
-
- @Autowired
- private Map<String, ServiceHandler<?>> handlerMap;
-
- @Override
- public void afterPropertiesSet() throws Exception {
- Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
- for (ServiceHandler handler : handlerMap.values()) {
- handlers.put(handler.type(), handler);
- }
- }
-
- @Override
- public void run() {
-
- }
- }
业务处理统一放入队列执行
定义队列数据对象:
- /**
- * 数据类型
- * @param <T>
- */
- @Data
- public class AbstractService<T> {
-
- ServiceType type;
- T data;
- }
管理队列任务:
- /**
- * 业务处理任务管理器
- */
- @Component
- public class ServiceTaskManger extends Thread implements InitializingBean {
-
- public static Queue<AbstractService> queue = new LinkedBlockingDeque<>();
-
- private static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();
-
- @Autowired
- private Map<String, ServiceHandler<?>> handlerMap;
-
- // 任务窃取线程池
- private ExecutorService executorService = Executors.newWorkStealingPool();
-
- @Override
- public void afterPropertiesSet() throws Exception {
- Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
- for (ServiceHandler handler : handlerMap.values()) {
- handlers.put(handler.type(), handler);
- }
- }
-
- @Override
- public void run() {
- while (true){
- int count = queue.size();
- // 处理任务条件:队列不为空
- if(count>0){
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < count; i++) {
- AbstractService service = queue.poll();
- ServiceHandler serviceHandler = handlers.get( service.getType());
- try{
- serviceHandler.execute(service.getData());
- }catch (Exception e){
- serviceHandler.handleException(service.getData());
- }
- }
- }
- });
- }
- }
- }
- }
任务管理API接口
- @RestController
- @RequestMapping("/services")
- public class ServiceTaskController {
-
- @RequestMapping("/account/save")
- public String accountSaveMoney(Account account){
- AccountService accountService = new AccountService();
- accountService.setType(ServiceType.ACCOUNT_SAVE_MONEY);
- accountService.setData(account);
- ServiceTaskManger.queue.add(accountService);
- return "success";
- }
-
- @RequestMapping("/account/withdraw")
- public String accountWithdrawMoney(Account account){
- AccountService accountService = new AccountService();
- accountService.setType(ServiceType.ACCOUNT_WITHDRAW_MONEY);
- accountService.setData(account);
- ServiceTaskManger.queue.add(accountService);
- return "success";
- }
-
- }
队列交互的接口适合跨系统异步业务。