Spring AOP基础

2017-06-22  本文已影响0人  luoxn28

IOC和AOP是Spring的两大基石,AOP(面向切面编程),是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP)。

在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组合,OOP 最大问题就是无法解耦组件进行开发。AOP 为开发者提供一种进行横切关注点(比如日志关注点)分离并织入的机制,把横切关注点分离,然后通过某种技术织入到系统中,从而无耦合的完成了我们的功能。

AOP世界中的居民

AOP中的通知类型

AOP程序示例

@Component
public interface HelloAop {
    void hello();
}

@Component
public class HelloAopImpl implements HelloAop{
    @Override
    public void hello() {
        System.out.println("---hello HelloAopImpl---");
    }
}

@Aspect
@Component
public class HelloAopAspect {
    @Before("execution(public void com.luo.aop.HelloAopImpl.hello())")
    public void beforeAdvice(JoinPoint point) {
        String methodName = point.getSignature().getName();
        System.out.println("beforeAdvice: " + methodName);
    }

    @After("execution(public void com.luo.aop.HelloAopImpl.hello())")
    public void afterAdvice(JoinPoint point) {
        String methodName = point.getSignature().getName();
        System.out.println("afterAdvice: " + methodName);
    }

    @AfterThrowing("execution(public void com.luo.aop.HelloAopImpl.hello())")
    public void afterThrowingAdvice(JoinPoint point) {
        String methodName = point.getSignature().getName();
        System.out.println("afterThrowingAdvice: " + methodName);
    }

    @AfterReturning("execution(public void com.luo.aop.HelloAopImpl.hello())")
    public void afterReturningAdvice(JoinPoint point) {
        String methodName = point.getSignature().getName();
        System.out.println("afterReturningAdvice: " + methodName);
    }

    @Around("execution(public void com.luo.aop.HelloAopImpl.hello())")
    public Object aroundAdvice(ProceedingJoinPoint point) {
        Object result = null;

        // 环绕通知(前通知)
        System.out.println("aroundAdvice start...");
        try {
            // 前置通知
            result = point.proceed(); // 目标方法执行
        } catch (Throwable throwable) {
            // 异常通知
            throwable.printStackTrace();
        }
        // 环绕通知(后通知)
        System.out.println("aroundAdvice end...");
        // 后置通知
        // 返回通知

        return result;
    }
}

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("springConfig.xml");

    HelloAop helloAop = ctx.getBean(HelloAop.class);

    helloAop.hello();
}

spring配置文件:

<!-- 自动扫描 -->
<context:component-scan base-package="com.luo.aop"/>

<!-- 使用AspjectJ自动生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
AOP通知输出结果

指定切面优先级

在同一个连接点上应用不止一个切面时, 除非明确指定, 否则它们的优先级是不确定的。切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定。实现 Ordered 接口, getOrder() 方法的返回值越小, 优先级越高.若使用 @Order 注解, 序号出现在注解中。

@Aspect
@Order(0)
@Component
public class HelloAspect2 { }

@Aspect
@Order(1)
@Component
public class HelloAspect { }

参考资料:

  1. 《Spring揭秘》AOP章节
  2. Spring学习之AOP总结帖
上一篇 下一篇

猜你喜欢

热点阅读