浅入java架构-Aspect-短信验证预处理

浅入java架构-Aspect-短信验证预处理

问题:

    当今的软件产品,无论是互联网系统还是传统软件系统,对于消息的通知,短信占有比例还是很大的。并且在各种场景都需要,比如:支付、下订单、认证,等等。那么对于这种使用及其平凡且与具体的业务又没有关联的单独功能模块,我们应该怎样思考与处理呢?

解决方案:

    1、A实现A的短信验证接口,B实现B的短信验证接口(代码太冗余,不易维护,将来不易重构、移植)

    2、写出公用的短信验证类,需要的时候,再去调用(可行,但与业务混合,不太好)

    3、定义父级抽象类(可行,但单继承设计不友好)

    4、利用切面,在执行指定方法之前,进行验证,我称为预处理(对开发的兄弟做业务处理时,做到主次分离,功能透明化)

当然,肯定还有n中不同的更好的处理方式,希望大家共享出来一起探讨,互相学习。

以上四种方式,我推崇第4种,废话少说,大家看实现:

一、创建操作通用接口,用于切割:IService

import com.jd.jr.hd.jsf.common.exception.ServiceException;

/**
 * @ClassName IService
 * @Description 操作通用接口
 * @author lisheng
 * @Date 2016年6月14日 下午1:40:15
 * @version 1.0.0
 * @param <R>
 * @param <T>
 */
public interface IService<R, T> {
	public T operate(R req) throws ServiceException;
}

二、创建短信验证前置接口:IPreSmsValidator

/**
 * @ClassName IPreSmsValidator
 * @Description 短信验证码前置验证接口
 * @author lisheng
 * @Date 2016年6月14日 下午1:39:25
 * @version 1.0.0
 * @param <T>
 */
public interface IPreSmsValidator<T extends SmsValidatorReq> {
}

三、创建业务接口,继承通用接口,这里以登录为例:LoginService

/**
 * @ClassName LoginService
 * @Description TODO(这里用一句话描述这个类的作用)
 * @author lisheng
 * @Date 2016年6月18日 下午9:20:06
 * @version 1.0.0
 */
public interface LoginService extends IService<LoginReq, LoginResp>,IPreSmsValidator<LoginReq> {
}

四、创建短信验证请求实体及:SmsValidatorReq

public class SmsValidatorReq implements Serializable {
	private static final long serialVersionUID = 5305903620897500977L;
	private String smsCode;
	public String getSmsCode() {
		return smsCode;
	}
	public void setSmsCode(String smsCode) {
		this.smsCode = smsCode;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("SmsValidatorReq [smsCode=");
		builder.append(smsCode);
		builder.append("]");
		return builder.toString();
	}
}

五、创建业务请求对象,继承短信验证实体:

public class LoginReq extends SmsValidatorReq {
	private static final long serialVersionUID = 8136730159412699592L;
	private String userId;
	private String password;
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this);
	}
}

六、创建业务实现类,继承登录接口:LoginServiceImpl

@Service
public class LoginServiceImpl implements LoginService {

	@AutoLogMethod("登录")
	@Override
	public LoginResp operate(@MethodParam("参数") LoginReq req) throws ServiceException {
		if(!"zhangsan".equals(req.getUserId())) {
			throw new ServiceException("-102", "用户名不存在");
		}
		if(!"123456".equals(req.getPassword())) {
			throw new ServiceException("-103", "密码不正确");
		}
		return new LoginResp("0", "登录成功");
	}
}

七、创建短信验证服务接口及实现类:SmsValidatorService,SmsValidatorServiceImpl

public interface SmsValidatorService {
	public void validate(SmsValidatorReq req) throws SmsValidatorException;
}

@Service
public class SmsValidatorServiceImpl implements SmsValidatorService {

	@Override
	public void validate(SmsValidatorReq req) throws SmsValidatorException {
		if(!"123456".equalsIgnoreCase(req.getSmsCode())) {
			throw new SmsValidatorException("-101", "验证码不正确", "123456");
		}
	}
}

八、创建短信验证前置切面:SmsAspect

/**
 * @ClassName SmsAspect
 * @Description 短信验证前置切面
 * @author lisheng
 * @Date 2016年6月14日 下午1:40:57
 * @version 1.0.0
 */
@Aspect
@Component
@Order(0)
public class SmsAspect {
	
	@Resource
	private SmsValidatorService smsValidatorService;
	
	@Pointcut("execution(* com.jd.jr.hd.jsf.service.IService.operate(..))")
	public void autoValidator() {
	}
	
	@Before("autoValidator()")
    public void before(JoinPoint joinPoint) {
		Object target = joinPoint.getTarget();
		if(target instanceof IPreSmsValidator){
			SmsValidatorReq req = null;
			if(null != joinPoint.getArgs() && joinPoint.getArgs().length > 0){
				req = (SmsValidatorReq) joinPoint.getArgs()[0];
			}
			smsValidatorService.validate(req);
		}
    }
	
	@Around("autoValidator()")
	public Object aroundValidator(ProceedingJoinPoint pjp) throws Throwable {
		return pjp.proceed();
	}
}

切割的类为统一执行类,判断切割的类是否为短信验证接口,如果是,则获取短信验证码请求参数,校验;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值