SSM笔记(4)——自定义注解与AOP切面

  • 目标

    使用自定义注解标记controller,前端传参调用该controller时,使用切面捕获方法,对传递来的参数添加createTime和createPerson(person从Session中获取),免去在每一个服务类中都要set这两个值

  • 自定义注解

    1. 注解基础
    1.1 注解的形式
      	public @interface Insert{}
    
    1.2 元注解

    可以给注解添加的注解称为“元注解”

    1.2.1 @Retention: 定义注解的保留策略
    属性字段保留策略
    @Retention(RetentionPolicy.SOURCE)注解仅存在于源码中,在class字节码文件中不包含
    @Retention(RetentionPolicy.CLASS)默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
    @Retention(RetentionPolicy.RUNTIME)注解会在class字节码文件中存在,在运行时可以通过反射获取到

    【注】生命周期 SOURCE < CLASS < RUNTIME ,即后者作用域包含前者

    1.2.2 @Target:定义注解的作用目标
    属性字段作用目标
    @Target(ElementType.TYPE)接口、类、枚举、注解
    @Target(ElementType.FIELD)字段、枚举的常量
    @Target(ElementType.METHOD)方法
    @Target(ElementType.PARAMETER)方法参数
    @Target(ElementType.CONSTRUCTOR)构造函数
    @Target(ElementType.LOCAL_VARIABLE)局部变量
    @Target(ElementType.ANNOTATION_TYPE)注解
    @Target(ElementType.PACKAGE)
    1.2.3 @Document:说明该注解将被包含在javadoc中
    1.2.4 @Inherited:说明子类可以继承父类中的该注解
    2. 自定义注解
    	@Target(ElementType.METHOD)
    	@Retention(RetentionPolicy.RUNTIME)
    	@Documented
    	public @interface Insert {
    	}
    

    自定义一个Insert注解,用于添加在controller方法上,生命周期为RUNTIME,用于识别是数据插入操作

  • AOP切面

    1. AOP基础
    1.1 注解基础
    1.1.1 通知
    属性字段作用域
    @Before在方法调用之前调用通知
    @After在方法完成之后调用通知,无论方法执行成功与否
    @AfterReturning在方法执行成功之后调用通知
    @AfterThrowing在方法抛出异常后进行通知
    @Around通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
    1.1.2 连接点
    • 连接点是一个应用执行过程中能够插入一个切面的点。
    • 连接点可以是调用方法时、抛出异常时、甚至修改字段时
    1.1.3 切点
    • 切点定义了AOP执行的位置
    • 切点是连接点的集合,通常使用正则表达式匹配多个连接点
    • 在SpringAOP中定义切点(使用AspectJ的切点表达式)
    指示器作用域
    arg ()限制连接点的指定参数为指定类型的执行方法
    @args ()限制连接点匹配参数由指定注解标注的执行方法
    execution ()用于匹配连接点的执行方法
    this ()限制连接点匹配 AOP 代理的 Bean 引用为指定类型的类
    target ()限制连接点匹配特定的执行对象,这些对象对应的类要具备指定类型注解
    within()限制连接点匹配指定类型
    @within()限制连接点匹配指定注释所标注的类型
    @annotation限制匹配带有指定注释的连接点
    1.1.4 切面
    • 切面是通知和切点的集合,定义了AOP执行什么和在哪执行
    1.1.5 引入
    • 引入允许我们向现有的类中添加方法或属性
    1.1.6 织入
    2. 自定义 AOP
@Component
@Aspect
public class SQLOperateAspect {
	//设置切点为@Insert标注的方法
	 @Before(value="@annotation(com.fzu.oqn.Insert)")
	 public void dofore(JoinPoint jp) {			 
         try {
         	 //获取方法入参对象
        	 Object[] objects = jp.getArgs();
        	 //获取入参对象的setCreateTime方法
        	 Method setCreateTime = objects[0].getClass().getMethod("setCreateTime", java.util.Date.class);
        	 //获取入参对象的setCreatePerson方法
        	 Method setCreatePerson = objects[0].getClass().getMethod("setCreatePerson", java.lang.String.class);
        	 //获取session对象的getAttribute方法
        	 Method session_getAttribute = objects[1].getClass().getMethod("getAttribute", java.lang.String.class);
        	 //通过反射获得Session对象中的信息
        	 User user = (User)session_getAttribute.invoke(objects[1], "loginUser");
        	 //通过反射操作函数赋值
        	 setCreateTime.invoke(objects[0], new Date());
        	 setCreatePerson.invoke(objects[0], user.getUserName());
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	 }
}
2.1 JoinPoint 对象
方法名功能
Signature getSignature();获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
Object[] getArgs();获取传入目标方法的参数对象
Object getTarget();获取被代理的对象
Object getThis();获取代理对象
  • 使用

@RequestMapping(value="/publishPaper",method= RequestMethod.POST)
	@Insert
	public ResponseMessage publishPaper(@RequestBody QuestionnairePublishVO questionnairePublishVO,HttpSession session) {
		User user = (User)session.getAttribute("loginUser");
		return myPapersService.publishPaper(questionnairePublishVO);
	}

在Controller上添加@Insert注解,调用该方法时AOP会进行拦截,获取第二个参数Session中的登陆者信息,赋值给第一个参数questionnairePublishVO中的createTime和createPerson属性

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值