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整合开发王者归来》

posted on 2017-12-04 17:07  乐之者v  阅读(1294)  评论(0编辑  收藏  举报

导航