九点钟☆方向

记录成长点滴

欢迎来到我的个人博客~


Spring笔记(九) Spring基于注解的AOP

目录

实现步骤

引入相关依赖

spring-context,aspectjweaver

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>

<!--junit测试相关-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
</dependencies>

业务层接口及实现类

//接口
public interface IAccountService {
	//接口方法
}


//实现类,并加入相应注解,交由Spring容器管理
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
    //实现接口方法
}

通知类(前置通知、后置通知、异常通知、最终通知)

//加入相应注解,交由Spring容器管理
@Component("logger")
//@Aspect表示当前类为切面类
@Aspect
public class Logger {

    @Pointcut("execution(* com.mg.service.impl.*.*(..))")
    private void pt1(){}

    //如果引用上面的方法,可以直接写@Before("execution(* com.mg.service.impl.*.*(..))")
    //前置通知
    @Before("pt1()")
    public void before() {
        System.out.println("before");
    }
    
    //后置通知
    @AfterReturning("pt1()")
    public void afterReturning() {
        System.out.println("afterReturning");
    }
    
    //异常通知
    @AfterThrowing("pt1()")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }
    
    //最终通知
    @After("pt1()")
    public void after() {
        System.out.println("after");
    }
    
    //环绕通知
    @Around("pt1()")
    public Object arroundLog(ProceedingJoinPoint pjp) {
        Object val = null;
        Object[] args = pjp.getArgs();
        try {
            System.out.println("前置通知");
            val = pjp.proceed(args);
            System.out.println("后置通知");
        } catch (Throwable throwable) {
            System.out.println("异常通知");
            throwable.printStackTrace();
        }finally {
            System.out.println("最终通知");
        }
        return val;
    }
}

注意Spring基于注解的AOP配置会存在执行调用顺序的问题所以注解开发时建议使用环绕通知的方式

@Before("pt1()")
引用方法时不要忘记后面的括号 pt1() 另外使用此种方法时注意aspectjweaver的版本问题如果版本过低会出现java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut pt1 异常测试时发现低于1.6.6的版本都会出现这个问题

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">


    <!--配置Spring创建容器时需要扫描的包-->
    <context:component-scan base-package="com.mg"></context:component-scan>

    <!--配置Spring开启注解AOP的支持-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

测试

@RunWith(SpringJUnit4ClassRunner.class)
//指定配置文件
@ContextConfiguration(locations = "classpath:bean.xml")
public class MyTest {
    @Autowired
    IAccountService accountService;

    @Test
    public void test1() {
        accountService.saveAccount();
    }
}

替换配置文件,使用纯注解方式

@Configuration
@ComponentScan(basePackages = {"com.mg"})
@EnableAspectJAutoProxy
public class SpringConfig {   }


测试时注意将配置文件改为配置类
@RunWith(SpringJUnit4ClassRunner.class)
//配置文件改为配置类
//@ContextConfiguration(locations = "classpath:bean.xml")
@ContextConfiguration(classes = SpringConfig.class)
public class MyTest {
    @Autowired
    IAccountService accountService;

    @Test
    public void test1() {
        accountService.saveAccount();
    }
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦