博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简述spring中常有的几种advice?
阅读量:5247 次
发布时间:2019-06-14

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

在Spring中,Advice都是通过Interceptor来实现的,主要有以下几种:

1. 环绕Advice:

//例子摘自Spring referencepublic interface MethodInterceptor extends Interceptor {      Object invoke(MethodInvocation invocation) throws Throwable;}public class DebugInterceptor implements MethodInterceptor {    public Object invoke(MethodInvocation invocation) throws Throwable {        System.out.println("Before: invocation=[" + invocation + "]");  //(1)        Object rval = invocation.proceed();        System.out.println("Invocation returned");  //(2)        return rval;    }}

环绕advice类似一个拦截器链,这个拦截器链的中心就是被拦截的方法。在程序(1)(2)我们可以加入我们自己的代码,以表示在方法执行前后我们需要干什么。invocation.proceed()方法运行指向连接点的拦截器链并返回proceed()的结果。

2. Before Advice

public interface MethodBeforeAdvice extends BeforeAdvice {    void before(Method m, Object[] args, Object target) throws Throwable;}

 一个更简单的通知类型是before 通知。它不需要 MethodInvocation对象,因为它只是在进入方法之前被调用。before advice的一个主要优点是它不需要调用proceed()方法,因此就不会发生 无意间运行拦截器链失败的情况。

3. After advice

public interface AfterReturningAdvice extends Advice {    void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;}!

一个After advice可以访问返回值(但不能进行修改),被调用方法,方法参数以及目标对象。

4.Throws Advice

//ThrowsAdvice 是一个空接口,起标识作用public interface ThrowsAdvice extends Advice {}//所给对象必须实现一个或者多个针对特定类型的异常通知方法,格式如下afterThrowing([Method], [args], [target], subclassOfThrowable)//只有最后一个参数是必须的。因此异常通知方法对方法及参数的需求,方法的签名将从一到四个参数之间变化。

最后还有一个是introduction advice,这个我想什么时候自己单独做个例子理解一下。

       做了个例子如下,想像一个用户登录场景:在登录之前,我们对其输入的用户名进行有效性检查;登录成功后,我们记上用户登录次数;如果登录失败,则进行异常处理。实现代码如下:

package com.learn.spring.test.advisor;//登录的业务代码public interface LoginService {    void login(String name, String password) throws UnauthorityException;}public class LoginServiceImpl implements LoginService {    public void login(String name, String password) throws UnauthorityException {            check(name, password);            System.err.println(name + " is logining system...");    }        private void check(String name, String password) throws UnauthorityException {            if("myyate".equals(name) && "pass".equals(password) ) {                     System.err.println(name + " passed check....");            } else {                    throw new UnauthorityException("invalid password");            }    }}
//用户名检查 拦截器public class LoginNameCheckInterceptor implements MethodBeforeAdvice {    public void before(Method method, Object[] args, Object target) throws Throwable {         System.err.println("check user's name is valid?");         if(args[0] == null || "".equals(args[0].toString().trim())) {               throw new IllegalArgumentException();         }    }}
//用户登录次数统计拦截器public class LoginCountInterceptor implements AfterReturningAdvice ...{    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable ...{    System.err.println("Counting the login counts of " + args[0]);    }}
//异常处理拦截器public class ExceptionThrowInterceptor implements ThrowsAdvice {        public void afterThrowing(Method m, Object[] args, Object target, IllegalArgumentException ex) throws Throwable {    System.err.println("Login name is wrong, exception: " + ex);    }        public void afterThrowing(Method m, Object[] args, Object target, UnauthorityException ex) {       System.err.println(target.getClass() + "." + m.getName() +            "() throw a exception: " + ex.getMessage());    }}

配置文件如下:

com.learn.spring.test.advisor.LoginService
loginNameCheckInterceptor
loginCountInterceptor
exceptionThrowInterceptor

测试代码运行:

 

public class Test {    public static void main(String[] args) throws Exception {        BeanFactory bf =             BeanFactoryFactory.getBeanFactory("beans.xml", Test.class);        LoginService ls = (LoginService) bf.getBean("loginService");        ls.login("myyate", "pass");    }}

输出结果:

 

check user's name is valid?myyate passed check....myyate is logining system...Counting the login counts of myyate

转载:https://blog.csdn.net/caolaosanahnu/article/details/7914595

转载于:https://www.cnblogs.com/cslgzl/p/10533335.html

你可能感兴趣的文章
java equals 小记
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>
YUV 格式的视频呈现
查看>>
Android弹出框的学习
查看>>
现代程序设计 作业1
查看>>
在android开发中添加外挂字体
查看>>
Zerver是一个C#开发的Nginx+PHP+Mysql+memcached+redis绿色集成开发环境
查看>>
多线程实现资源共享的问题学习与总结
查看>>
Learning-Python【26】:反射及内置方法
查看>>
torch教程[1]用numpy实现三层全连接神经网络
查看>>
java实现哈弗曼树
查看>>
转:Web 测试的创作与调试技术
查看>>
python学习笔记3-列表
查看>>
程序的静态链接,动态链接和装载 (补充)
查看>>
关于本博客说明
查看>>
线程androidAndroid ConditionVariable的用法
查看>>
stap-prep 需要安装那些内核符号
查看>>
转载:ASP.NET Core 在 JSON 文件中配置依赖注入
查看>>
socket初识
查看>>