spring学习(三) —— AOP

一、注解解释

  1. @EnableAspectJAutoProxy: 开启springAOP代理功能
  2. @Aspect:把当前类标识为一个切面供容器读取
  3. @Pointcut:声明全局切入点,声明的方法只是该注解的载体,具体切入点只需引入载体即可
  4. @Before:前置通知
  5. @AfterReturning:后置通知
  6. @Around:环绕通知   即:前置通知 + 后置通知
  7. @After:最终通知
  8. @AfterThrowing:异常通知

二、实现AOP功能

  • 导入jar包
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>         
  • 继续上一个测试demo,创建test2

  • 创建接口
package com.test.spring.test3;

public interface TestAop {

    void testAop1();
}
  • 创建实现类,并注册为Bean
package com.test.spring.test3;

import org.springframework.stereotype.Component;

@Component
public class TestAopImpl implements TestAop {

    @Override
    public void testAop1() {
        System.out.println("TestAopImpl.testAop1()");
    }
}
  • 创建切面
package com.test.spring.test3.aop;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 需要将定义的切面类注册到springIOC容器中,否则spring无法实现aop功能(因为spring没有切面类的           实例)  
 */
@Aspect
@Component
public class FirstTangent {

    @Pointcut("execution(public * com.test.spring.test3.TestAopImpl.testAop1(..))")
    public void url(){}

    /**
     *  前置通知
     */
    @Before("url()")
    public void testBefore(){
        System.out.println("testBefore");
    }
    /**
     *  后置通知
     */
    @AfterReturning("url()")
    public void testAfterReturning(){
        System.out.println("testAfterReturning");
    }
    
 }
  • 创建Config
package com.test.spring.test3;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


/**
 * @EnableAspectJAutoProxy     ---  开启springAOP代理功能
 */
@ComponentScan
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {

}
  • 编写测试代码
package com.test.spring.test3;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class)
public class Test3 {

    @Autowired
    private TestAop testAop;

    @Test
    public void TestAop(){
        testAop.testAop1();
    }
}
  • 测试结果

三、关于环绕通知

编写环绕通知需要使用参数ProceedingJoinPoint,当前置通知执行完毕后使用proceed方法放行,当目标方法执行完毕后会返回到此通知方法,继续执行后置通知

  • 修改FirstTangent类添加环绕通知方法
@Aspect
@Component
public class FirstTangent {

    @Pointcut("execution(public * com.test.spring.test3.TestAopImpl.testAop1(..))")
    public void url(){}

    /**
     *  前置通知
     */
    //@Before("url()")
    public void testBefore(){
        System.out.println("testBefore");
    }

    //@AfterReturning("url()")
    public void testAfterReturning(){
        System.out.println("testAfterReturning");
    }

    //@AfterThrowing("url()")
    public void testAfterThrowing(){
        System.out.println("testAfterThrowing");
    }

    @Around("url()")
    public void testAround(ProceedingJoinPoint pjp){
        //----------前置-----------
        System.out.println("testAround1");
        
        //----------执行目标方法-----------
        try {
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        //-------------后置-----------------
        System.out.println("testAround2");
    }
}
  • 测试环绕通知

四、利用AOP拦截注解

只需修改全局切入点即可:

      如:@Pointcut("@annotation(com.test.spring.multi_data_source.annotation.DataSource)")

      哈哈,使用自定义注解的时候是不是方便了很多

猜你喜欢

转载自blog.csdn.net/qq_42407917/article/details/95619407