• SpringAop及拦截器


    一、Aop

    Aop,面向切面编程,提供了一种机制,在执行业务前后执行另外的代码。

    切面编程包括切面(Aspect),连接点(Joinpoint)、通知(Advice)、切入点(Pointcut)、引入(Introduction)

    通知(Advice)又分为前置通知,后置通知,最终通知,环绕通知,异常通知等。

    在Spring中,Aop思想可以通过拦截器体现。

    二、Aop应用:

    1.Junit单元测试中,也用到了AOP思想,比如其中的before(),after()方法。

    2.事务管理。业务逻辑之前是事务的开启begin,业务逻辑之后是事务的提交commit。

    3.日志的管理。过滤,格式处理等

    4.Spring中的拦截器。

    三、拦截器:
    在Spring中,拦截器可以分为方法前执行的拦截器、方法后执行的拦截器、异常拦截器
    1.方法前拦截器类,需要实现MethodBeforeAdvice接口;
    2.方法后拦截器类,需要实现AfterReturningAdvice接口;
    3.异常拦截器类,需要实现ThrowsAdvice接口.
    四、拦截器中的Aop及代理模式:

    Advisor(通知):实现了Advice接口的拦截器(interceptor),是AOP中的Advisor(通知)
    Pointcut(切入点):NameMatchMethodPointcutAdvisor类是AOP中的Pointcut(切入点),
    将各种拦截器配置到NameMatchMethodPointcutAdvisor上。
    "切入点"负责指定区域,而"通知"负责插入指定的代码。
    Spring无法将Service实现类与拦截器类直接组装,因此没有对应的getter、setter方法,
    安装时借助的是Spring的代理类ProxyFactoryBean,即把拦截器安装到切入点NameMatchMethodPointcutAdvisor中,
    把自定义的Service安装到ProxyFactoryBean中,然后组装在一起.(代理模式)

    ProxyFactoryBean通过setInterceptorNames()方法设置拦截器,通过setTarget()方法设置拦截对象,可以在xml中配置 。

    五、区分Filter(过滤器)和Interceptor(拦截器):

    四、示例如下:

    Service接口:

    public interface IAopService {
        public void withAop() throws Exception;
        public void withoutAop() throws Exception;
    }

    Service接口实现类:

    import javax.security.auth.login.AccountException;
    
    public class AopServiceImpl implements IAopService {
        private String name;
    
        @Override
        public void withAop() throws Exception {
            System.out.println("有AOP的函数运行。name: " + name);
            if (name.trim().length() == 0) {
                throw new AccountException("name属性不能为空");
            }
        }
    
        @Override
        public void withoutAop() throws Exception {
            System.out.println("没有AOP的函数运行。");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    三个拦截器如下所示:

    方法前拦截器如下:

    import org.springframework.aop.MethodBeforeAdvice;
    import java.lang.reflect.Method;
    
    public class MethodBeforeInterceptor implements MethodBeforeAdvice {
    
        @Override
        public void before(Method method, Object[] args, Object instance)
                throws Throwable {
            System.out.println("即将要执行方法:" + method.getName());
            if (instance instanceof AopServiceImpl) {
                String name = ((AopServiceImpl) instance).getName();
                if (name == null)  {
                    throw new NullPointerException("name属性不能为null");
                }
            }
        }
    }

    方法后拦截器如下:

    import org.springframework.aop.AfterReturningAdvice;
    
    import java.lang.reflect.Method;
    
    public class MethodAfterInterceptor implements AfterReturningAdvice {
        @Override
        public void afterReturning(Object value, Method method, Object[] args,
                                   Object instance) throws Throwable {
            System.out.println("方法 " + method.getName() + "运行完毕,返回值为:" + value);
        }
    }

    异常拦截器如下:

    import org.springframework.aop.ThrowsAdvice;
    
    import javax.security.auth.login.AccountException;
    import java.lang.reflect.Method;
    
    public class ThrowsInterceptor implements ThrowsAdvice {
        public void afterThrowing(Method method, Object[] args, Object instance,
                                  AccountException ex) throws Throwable {
            System.out.println("方法" + method.getName() + " 抛出了异常:" + ex);
        }
    
        public void afterThrowing(NullPointerException ex) throws Throwable {
            System.out.println("抛出了异常:" + ex);
        }
    }

    Main方法如下:

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AopRun {
        public static void main(String[] args) throws Exception {
            ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
            IAopService aopService = (IAopService) context.getBean("aopService");
            aopService.withAop();
            aopService.withoutAop();
        }
    }

    applicationContext.xml如下:

     <!--将拦截器配置到代理类上-->
        <bean id="aopService" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!--拦截器-->
            <property name="interceptorNames">
                <list>
                   <value>aopMethodBeforeInterceptor</value>
                    <value>aopMethodAfterInterceptor</value>
                   <value>aopThrowInterceptor</value>
                </list>
            </property>
            <!--拦截对象 -->
            <property name="target">
                <bean class="com.aop.AopServiceImpl">
                    <property name="name" value="Rui"></property>
                </bean>
            </property>
        </bean>

    <!--拦截器在方法前运行,安装到NameMatchMethodPointcutAdvisor-->
        <bean id="aopMethodBeforeInterceptor"
          class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
            <property name="advice">
                <bean class="com.aop.MethodBeforeInterceptor"></bean>
            </property>
            <property name="mappedName" value="withAop"></property>
        </bean>

        <!--拦截器在方法后运行,安装到NameMatchMethodPointcutAdvisor-->
        <bean id="aopMethodAfterInterceptor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
              <property name="advice" >
                  <bean class="com.aop.MethodAfterInterceptor"></bean>
              </property>
              <property name="mappedName" value="withAop"></property>
        </bean>

        <!--拦截器在异常抛出运行,安装到NameMatchMethodPointcutAdvisor-->
        <bean id="aopThrowInterceptor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
            <property name="advice">
                <bean class="com.aop.ThrowsInterceptor"></bean>
            </property>
            <property name="mappedName" value="withAop"></property>
        </bean>

     注:示例摘自《JavaWeb整合开发王者归来》

  • 相关阅读:
    USB描述符(转)
    (转)Linux设备驱动之HID驱动 源码分析
    Linux USB 鼠标驱动程序详解(转)
    (转)linux如何获取鼠标相对位置信息
    从零写一个编译器(四):语法分析之构造有限状态自动机
    从零写一个编译器(三):语法分析之几个基础数据结构
    从零写一个编译器(二):语法分析之前置知识
    从零写一个编译器(一):输入系统和词法分析
    自底向上语法分析
    递归下降和LL(1)语法分析
  • 原文地址:https://www.cnblogs.com/expiator/p/7977975.html
Copyright © 2020-2023  润新知