文档章节

SpringAop的使用

丶KKdo
 丶KKdo
发布于 2016/11/08 13:29
字数 806
阅读 15
收藏 0

要用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<? extends Interceptor> 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
@Component
public 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方法进行验证, 可以在前台看一下效果:

© 著作权归作者所有

上一篇: jbdc编程示例
丶KKdo
粉丝 1
博文 24
码字总数 13683
作品 0
成都
程序员
私信 提问
Spring系列之AOP基本主要类概述

在这篇文章中我将对自己了解的AOP中的基本主要类做一个概述,可能不包括一些AOP高级用法的类以及是自己还不了解的类。会不定期的进行补充和修改。 SpringAOP基础解析类 类名 作用概述 AopNam...

Mr_zebra
2018/07/20
0
0
Spring AOP之同一个对象方法内部自调用导致事务失效问题

对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,SpringAOP,就切入不...

xiaomin0322
05/20
0
0
Spring中事务内部调用引发的惨案

在一个类内部有2个方法foo和bar,其中bar方法配有注解(@Transactional),即bar是事务执行的,而foo不是事务执行,当foo方法内部调用bar方法后,bar方法的事务是不生效的。示例代码如下: pub...

hnrpf
2016/04/14
226
0
Spring系列之Spring框架和SpringAOP集成过程分析(十)

在开始这个系列之前大家先想一下我们是怎么在项目中使用SpringAOP的(这里的分析都是基于AspectJ注解的)。我们需要在我们的Spring配置文件中引入SpringAOP的命名空间和标签,然后定义切面Bea...

木叶之荣
2018/06/18
0
0
AOP的基本概念

AOP框架能处理程序执行中特定切入点(Pointcut),而不与具体某个类耦合。 下面是面向切面编程的一些术语: 概念 描述 切面(Aspect) 业务流程运行的某个特定步骤,即关注点,关注点可能横切多个...

shamgod_code
2016/10/30
23
0

没有更多内容

加载失败,请刷新页面

加载更多

如何使用 rsync 备份 Linux 系统的一些介绍

备份一直是 Linux 世界的热门话题。回到 2017,David Both 为 Opensource.com 的读者在使用 rsync 备份 Linux 系统方面提了一些建议,在这年的更早时候,他发起了一项问卷调查询问大家,在 ...

xiangyunyan
48分钟前
1
0
二进制位操作

单片机,或者一些模块的设置操作,都是由一个字节数据来完成,每位各有定义。就需进行位操作来组合需要的数字结果。 以JavaScript为例,编写位操作。 我们期望得到这样一个二进制数:0101101...

format
今天
4
0
聊聊中国的通信行业:从“七国八制”到“中华”脊梁

本期文章和大家一起来聊一聊我曾经从事过的通信行业吧。最近各方面信息的泛滥,包括和华为的同学聊天,自己确实也感慨颇多。想想我自己本科主修通信工程,研究生再修信息与通信工程,从本科开...

CodeSheep
今天
10
0
MDK:ARM M451M:exceed the range of code meory, continue to erase or not?

问题: 代码空间超限 几天前就遇到:exceed the range of code meory, continue to erase or not? 如下所示: 解决过程 开始以为中MDK软件的128KB限制,如是就不能生成HEX文件,应该链接时有提...

SamXIAO
今天
4
1
OSChina 周六乱弹 —— 因违反《中华人民共和国治安管理处罚法》第四十四条之规定

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoshiyue :#今日歌曲推荐# 惊艳分享谷微的单曲《安守本份》(@网易云音乐) 《安守本份》- 谷微 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
今天
735
15

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部