Spring详解篇之 AOP面向切面编程

一、概述

Aop(aspect oriented programming面向切面编程),是spring框架的另一个特征。AOP包括切面、连接点、通知(advice)、切入点(pointCut) 。

1.aop几个概念:

  • 横切关注点: 对哪些方面进行拦截,拦截后怎么处理。
  • 切面(aspect):切面是横切关注点的抽象。
  • 连接点(joinpoint):被拦截的方法
  • 切入点(pointcut):对连接点进行拦截的定义。
  • 通知(advice):拦截到连接点之后要执行的代码
  • 目标对象:代理的目标对象
  • 织入
  • 引入

2.主要功能:

  • 日志记录
  • 性能统计
  • 安全控制
  • 事物处理
  • 异常处理

3.advice类型:

  • 前置通知(before advice)
  • 返回后通知(after returning advice)
  • 抛出异常后通知(after throwing advice)
  • 后通知(after advice)
  • 环绕通知(around advice)

4.Spring对AOP的支持

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。

二、基于xml配置的aop

在spring基于schemel中,aop需要声明一个切面aspect,一个pointcut,一个advisor. 举个例子:

切面:

“` public class MoocAspect {

public void before() {
    System.out.println("MoocAspect before.");
}

}

“`

切点:

“` public class AspectBiz {

public void biz() {
    System.out.println("AspectBiz biz.");

// throw new RuntimeException(); }

“`

配置文件:

“`

三、基于spring api方式配置aop

直接上代码:

接口中有两个方法,一个基于aop,会被拦截 ,另外一个不会被拦截。

public interface IAopService {

    public void withAop() throws Exception;

    public void withoutAop() throws Exception;

}

实现类:

public class AopServiceImpl implements IAopService {

    private String name="forezp";

    public void withAop() throws Exception {

        System.out.println("with aop run: " + name);

        if (name.trim().length() == 0)
            throw new AccountException("name cannot be null");
    }

    public void withoutAop() throws Exception {
        System.out.println("without aop");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

方法前拦截器,实现MethodBeforeAdvice,在制定方法前会被调用。

public class MethodBeforeInterceptor implements MethodBeforeAdvice {

    public void before(Method method, Object[] args, Object instance)
            throws Throwable {

        System.out.println("method invoke:" + method.getName());

        if (instance instanceof AopServiceImpl) {

            String name = ((AopServiceImpl) instance).getName();

            if (name == null)
                throw new NullPointerException("name cannot be null");
        }

    }

}

返回后拦截器,执行指定方法后会被调用。

public class MethodAfterInterceptor implements AfterReturningAdvice {

    public void afterReturning(Object value, Method method, Object[] args,
            Object instance) throws Throwable {

        System.out.println("method  " + method.getName() + "had finished and return value-" + value);

    }

}

异常拦截器,当出现异常时拦截:

public class ThrowsInterceptor implements ThrowsAdvice {

    public void afterThrowing(Method method, Object[] args, Object instance,
            AccountException ex) throws Throwable {

        System.out.println("method" + method.getName() + " throws exception:" + ex);
    }

    public void afterThrowing(NullPointerException ex) throws Throwable {

        System.out.println("the exception:" + ex);
    }

}

三个拦截器和Servce实现类需要配置到spring中。实际上,spring无法组装,需要借助代理类,把拦截器安装到NameMatchMethodPointcutAdvisor中,把自定义的bean安装到ProxyFactoryBean中,然后组装在一起:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

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

    <!-- 拦截器 在 withAop() 返回后运行 -->
    <bean id="aopMethodAfterInterceptor"
        class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice">
            <bean
                class="com.imooc.aop.example2.MethodAfterInterceptor" />
        </property>
        <property name="mappedName" value="withAop"></property>
    </bean>

    <!-- 拦截器 在异常抛出后运行 -->
    <bean id="aopThrowsInterceptor"
        class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice">
            <bean
                class="com.imooc.aop.example2.ThrowsInterceptor" />
        </property>
        <property name="mappedName" value="withAop"></property>
    </bean>

    <bean id="aopService"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 拦截器 -->
        <property name="interceptorNames">
            <list>
                <value>aopMethodBeforeInterceptor</value>
                <value>aopMethodAfterInterceptor</value>
                <value>aopThrowsInterceptor</value>
            </list>
        </property>
        <!-- 被拦截的对象 -->
        <property name="target">
            <bean
                class="com.imooc.aop.example2.AopServiceImpl">

                    <property name="name" value="forezp"></property>

            </bean>
        </property>
    </bean>

</beans>

单元测试:

method invoke:withAop with aop run: forezp method withAophad finished and return value-forezp without aop

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏dalaoyang

SpringBoot文件上传下载

项目中经常会有上传和下载的需求,这篇文章简述一下springboot项目中实现简单的上传和下载。 新建springboot项目,前台页面使用的thymeleaf...

2939
来自专栏Android学习之路

Android 导入现有数据库

16811
来自专栏Kevin-ZhangCG

[ SSH框架 ] Spring框架学习之二(Bean的管理和AOP思想)

2055
来自专栏vue

.Net File类的操作

  File.Create(@"C:\Users\wjl\Desktop\Text.txt"); //文件的路径必须要存在,若不存在将产生异常

882
来自专栏腾讯Bugly的专栏

小程序组件化框架 WePY 在性能调优上做出的探究

导语 性能调优是一个亘古不变的话题,无论是在传统H5上还是小程序中。因为实现机制不同,可能导致传统H5中的某些优化方式在小程序上并不适用。因此必须另开辟蹊径找出...

4474
来自专栏Hongten

lucene(全文搜索)_恢复/更新索引操作

683
来自专栏Java学习之路

10 Spring框架 AOP (三) Spring对AspectJ的整合

上两节我们讲了Spring对AOP的实现,但是在我们的开发中我们不太使用Spring自身的对AOP的实现,而是使用AspectJ,AspectJ是一个面向切面的...

2879
来自专栏Android机动车

Dalvik、ART与JVM之间的关系

913
来自专栏bboysoul

解决proxychains的一个错误

ERROR: ld.so: object 'libproxychains.so.3' from LD_PRELOAD cannot be preloaded (...

412
来自专栏用户画像

Spring AOP和IOC

Spring的核心机制是依赖注入(Dependency Inversion),也称为控制反转(IOC)。所谓依赖注入,就是指运行工程中,如果需要调用另一个对象协...

531

扫码关注云+社区