基于注解的AOP配置之四种通知(不建议)
2021/4/7 18:08:47
本文主要是介绍基于注解的AOP配置之四种通知(不建议),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、 创建maven的jar工程,导入依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> </dependencies>
2、 编写业务层的接口
public interface IAccountService { /** * 模拟保存账户 */ void saveAccount(); }
3、编写业务层接口的实现类:
@Service("accountService") public class AccountServiceImpl implements IAccountService{ @Override public void saveAccount() { System.out.println("执行了保存"); // int i=1/0; } }
4、 创建一个具有公共代码的类
@Component("logger") @Aspect//表示当前类是一个切面类public class Logger { @Pointcut("execution(* com.itheima.service.impl.*.*(..))") private void pt1(){} //前置通知 @Before("pt1()") public void beforePrintLog(){ System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。"); } //后置通知 @AfterReturning("pt1()") public void afterReturningPrintLog(){ System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。"); } // 异常通知 @AfterThrowing("pt1()") public void afterThrowingPrintLog(){ System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。"); } //最终通知 @After("pt1()") public void afterPrintLog(){ System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。"); } }
在Logger类上面写@Aspect注解,表示当前类是一个切面类。
前置通知用@Before("pt1()")注解,
后置通知用@AfterReturning("pt1()")注解,
异常通知用@AfterThrowing("pt1()")注解,
最终通知用@After("pt1()")注解,
环绕通知用@Around("pt1()")注解
在Logger类中定义一个方法pt1,使用@Pointcut注解指定切入点表达式
注意引用切入点表达式时,@Before、@AfterReturning、@AfterThrowing、@After注解中的pt1后面的()一定要加上,否则会报错。
5、编写配置文件bean.xml,配置spring创建容器时要扫描的包
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置spring创建容器时要扫描的包--> <context:component-scan base-package="com.itheima"></context:component-scan> <!-- 配置spring开启注解AOP的支持--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
6、测试
public class AOPTest { public static void main(String[] args) { //1.获取容器 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); // ApplicationContext ac = new AnnotationConfigApplicationContext(Logger.class); //2.获取对象 IAccountService as = (IAccountService)ac.getBean("accountService"); //3.执行方法 as.saveAccount(); } }
结果:
发现最终通知在后置通知之前先执行,
发现最终通知在异常通知之前先执行,
Spring基于注解的AOP中,这四个通知类型确实有顺序调用的问题,所以在实际开发中一般选择用环绕通知。因为环绕通知不存在这个问题,因为代码是我们自己写的,我们想让他们什么时候执行就什么时候执行,故如果是基于注解的AOP,建议用环绕通知,因为前面四个通知在执行调用顺序上有问题。
不使用XML而是使用纯注解实现AOP:
1、注释掉bean.xml中的
2、给Logger类添加注解
@Configuration @Component("logger") @Aspect//表示当前类是一个切面类 @ComponentScan(basePackages = "com.itheima") @EnableAspectJAutoProxy public class Logger { @Pointcut("execution(* com.itheima.service.impl.*.*(..))") private void pt1(){} //前置通知 @Before("pt1()") public void beforePrintLog(){ System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。"); } //后置通知 @AfterReturning("pt1()") public void afterReturningPrintLog(){ System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。"); } // 异常通知 @AfterThrowing("pt1()") public void afterThrowingPrintLog(){ System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。"); } //最终通知 @After("pt1()") public void afterPrintLog(){ System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。"); } }
使用注解@ComponentScan(basePackage=“com.itheima”)替换<context:component-scan>标签
使用@EnableAspectJAutoProxy替换<aop:aspectj-autoproxy>标签。
3、测试:
public class AOPTest { public static void main(String[] args) { //1.获取容器 // ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); ApplicationContext ac = new AnnotationConfigApplicationContext(Logger.class); //2.获取对象 IAccountService as = (IAccountService)ac.getBean("accountService"); //3.执行方法 as.saveAccount(); } }
结果:
这篇关于基于注解的AOP配置之四种通知(不建议)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23JAVA语音识别项目入门教程
- 2024-11-23Java云原生学习:从入门到实践
- 2024-11-22Java创业学习:初学者的全面指南
- 2024-11-22JAVA创业学习:零基础入门到实战应用教程
- 2024-11-22Java创业学习:从零开始的Java编程入门教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22JAVA对接阿里云智能语音服务学习教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22Java副业学习:零基础入门到实战项目
- 2024-11-22Java副业学习:零基础入门指南