博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringAop的使用
阅读量:6452 次
发布时间:2019-06-23

本文共 5388 字,大约阅读时间需要 17 分钟。

  hot3.png

要用Spring的AOP需要引入两个aspectj的包,aspectjrt和aspectjweaver.

配置文件中要加入<aop:aspectj-autoproxy />

给需要的类加上@Aspect注解表示这是一个切面方法,还有需要加上@Component来交给spring的bean管理.

AOP还有很多的用法, 使用自带的@Before, @After注解等等, 下面用一种自己写注解实现AOP的方式.

用来实现web应用controller层调用方法前执行参数验证.

首先, 编写一个Before注解.

/** * 用于方法执行前拦截 */@Inherited@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface Before {	Class
value();}

Interceptor接口:

public interface Interceptor {	/**   	 * 拦截逻辑	 * @param inv	 * @return Object	*/	Object intercept(Invocation inv);}

Invocation类:用来获取类, 方法, 以及参数和request.

public class Invocation {	private Class
clazz; private Method method; private Object[] args; private HttpServletRequest request; public Invocation(Class
clazz, Method method, Object[] args, HttpServletRequest request) { this(method, args, request); this.request = request; } public Invocation(Class
clazz, Method method, Object[] args) { this.clazz = clazz; this.method = method; this.args = args; } public Invocation(Method method, Object[] args, HttpServletRequest request) { super(); this.method = method; this.args = args; this.request = request; } public Class
getClazz() { return clazz; } public void setClazz(Class
clazz) { this.clazz = clazz; } public Method getMethod() { return method; } public void setMethod(Method method) { this.method = method; } public Object[] getArgs() { return args; } public void setArgs(Object[] args) { this.args = args; } public HttpServletRequest getRequest() { return request; } public void setRequest(HttpServletRequest request) { this.request = request; } }

编写一个切面类来使用@Before注解

@Aspect@Componentpublic class BeforeAop {	@Pointcut(value = "@annotation(com.kkdo.core.annotation.Before)")	private void cutBefore() {	}		@Around("cutBefore()")	public Object doBefore(ProceedingJoinPoint point) throws Throwable {		HttpServletRequest request = HttpKit.getRequest();		MethodSignature ms = (MethodSignature) point.getSignature();		Method method = ms.getMethod();		Object[] args = point.getArgs();		Class
clazz = point.getTarget().getClass(); Before before = method.getAnnotation(Before.class); Interceptor ic = before.value().newInstance(); //拦截器进行校验,返回校验结果,如果没有错误,那么执行下去 Object result = ic.intercept(new Invocation(clazz, method, args, request)); //Object result = ic.intercept(new Invocation(clazz, method, args)); if(result == null) { return point.proceed(); } else { return result; } }}

这个切面类就表示在注解有@Before的方法前会执行, 这里的doBefore获取到拦截类, 方法以及参数.

AOP的使用:

@Before(PasswordVaildator.class)  //这里使用自己编写的@Before注解	@ResponseBody	@RequestMapping("editPassword")	public AjaxResult editPasswrod() {		String newPassword = getParameter("newPassword");		int id = getParameterToInt("id");		String accountName = getParameter("accountName");		User user = new User();		user.setPassword(newPassword);		user.setAccountName(accountName);		PasswordHelper.encryptPassword(user);		String sql = "UPDATE USER LU SET LU.PASSWORD = '{}', LU.SALT = '{}' WHERE LU.ID = {}";		sql = StrKit.format(sql, user.getPassword(), user.getSalt(), id);		Condition condition = new Condition(sql);		userMapper.updateBySql(condition);		//int a = 1/0;   事务测试		return success("修改密码成功!是否关闭窗口?");	}

这里的PasswordVaildator.class是实现了Interceptor接口的一个类,

public class PasswordVaildator extends KkdoValidator {	@Override	protected void doValidate(Invocation inv) {		validateRequired("newPassword", "请输入新密码");		validateRequired("confirmPassword", "请确认您的密码");		vailequal("newPassword", "confirmPassword");		vaildateLength("newPassword", 6, 18);	}	private void vaildateLength(String field, int min, int max) {		String value = request.getParameter(field);		if(value.length() < min) {			succeed = false;			result.addError("密码太简单,请输入"+ min + "位以上密码!");		}		if(value.length() > max) {			succeed = false;			result.addError("密码太长,请不要超过 + "+ max + "位!");		}	}		private void vailequal(String field1, String field2) {		String value1 = request.getParameter(field1);		String value2 = request.getParameter(field2);		if(!StrKit.equals(value1, value2)) {			succeed = false;			result.addError("两次密码不一致!");		}	}}

KkdoVaildator:

public abstract class KkdoValidator extends Interceptor {	protected boolean succeed = true;	protected HttpServletRequest request;    protected AjaxResult result = new AjaxResult();		protected static final String EMAIL_ADDRESS_PATTERN = "\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b";	final public Object intercept(Invocation inv) {		KkdoValidator validator = null;		try {			validator = getClass().newInstance();		} catch(Exception e ) {			throw new RuntimeException(e);		}		validator.request = inv.getRequest();		try {			validator.doValidate(inv);		} catch (Exception e) {			e.printStackTrace();		}		if(validator.succeed) {			return invoke();		} else {			//这里还需要改			return validator.result;		}	}		/**	 * Use validateXxx method to validate the parameters of this action.	 */	protected abstract void doValidate(Invocation inv);		/**	 * Validate Required. Allow space characters.	 */	protected void validateRequired(String field, String errorMessage) {		String value = request.getParameter(field);		if (value == null || "".equals(value))			request.setAttribute("error", errorMessage);	}}

这样,在intercept中进行validate方法进行验证, 可以在前台看一下效果:

转载于:https://my.oschina.net/kkdo/blog/783711

你可能感兴趣的文章
Entity Framwork CodeFirst 学习笔记五:数据库映射的默认配置和设置
查看>>
ant 执行java文件,java文件中含中文,显示乱码
查看>>
IE8兼容@media和mp4视频的解决方案
查看>>
第二周总结
查看>>
ASP.NET完整打包卸载更新攻略(By Installshield 2010)
查看>>
[120_移动开发Android]006_android开发之数据存储之sdcard访问
查看>>
[若有所悟]IT小兵总结IT人特点及挽留IT人才的九大策略
查看>>
概率图模型建模、学习、推理资料总结
查看>>
【转】知道这20个正则表达式,能让你少写1,000行代码
查看>>
自定义 启动和关闭 oracle 的命令
查看>>
用ASP.NET Core 2.0 建立规范的 REST API
查看>>
SQLite数据库、ListView控件的使用
查看>>
Storm程序的并发机制(重点掌握)
查看>>
Quartz
查看>>
正则表达式介绍
查看>>
初识Scala反射
查看>>
第三十九天
查看>>
Redis详解
查看>>
4Sum——LeetCode
查看>>
论程序员加班的害处
查看>>