Spring-AOP注解开发

微信公众号:Java修炼手册
关注可获取3T免费学习资料,助你从0到1;

**AOP注解开发**
***AOP代码实现(执行计算前后输入输出目标代码)***
1 定义一个业务逻辑类(MathCalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常)

1 public class MathCalculator {
2 public int div(int i,int j){
3 System.out.println("MathCalculator...div...");
4 return i/j;
5 }
6}

```
2 定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;

[email protected]
2public class LogAspects {
3
4 //抽取公共的切入点表达式
5 //1、本类引用
6 //2、其他的切面引用
7 @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
8 public void pointCut(){};
9
10 //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
11 //1使用引入切点方法
12 //joinPoint:用获取方法信息
13 @Before("pointCut()")
14 public void logStart(JoinPoint joinPoint){
15 Object[] args = joinPoint.getArgs();
16 System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
17 }
18 //2使用引用外部切点类的方法
19 @After("com.atguigu.aop.LogAspects.pointCut()")
20 public void logEnd(JoinPoint joinPoint){
21 System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
22 }
23
24 //JoinPoint一定要出现在参数表的第一位
25 @AfterReturning(value="pointCut()",returning="result")
26 public void logReturn(JoinPoint joinPoint,Object result){
27 System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
28 }
29 //joinPoint必须在返回值前面!!
30 @AfterThrowing(value="pointCut()",throwing="exception")
31 public void logException(JoinPoint joinPoint,Exception exception){
32 System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
33 }
34}

  

通知方法:

@Aspect声明这是一个切面类

前置通知(@Before):logStart:在目标方法(div)运行之前运行

后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)

返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行

异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行

环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())

3 将切面类和业务逻辑类(目标方法所在类)都加入到容器中;

```java
[email protected]
[email protected]
3public class MainConfigOfAOP {
4
5 //业务逻辑类加入容器中
6 @Bean
7 public MathCalculator calculator(){
8 return new MathCalculator();
9 }
10
11 //切面类加入到容器中
12 @Bean
13 public LogAspects logAspects(){
14 return new LogAspects();
15 }
16}
```

给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】!!!

4 测试

1public class IOCTest_AOP {
2
3 @Test
4 public void test01(){
5 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
6
7 //1、不要自己创建对象
8// MathCalculator mathCalculator = new MathCalculator();
9// mathCalculator.div(1, 1);
10 MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
11
12 mathCalculator.div(1, 0);
13
14 applicationContext.close();
15 }
16
17}

  

只有在spring容器内的对象才能使用aop功能,所以使用的时候不能自己new一个对象,而是从容器获取!!!

运行结果:

1div运行。。。@Before:参数列表是: {[1, 1]}
2MathCalculator. . .div. . .
3div结束。。。@After
4div正常返回。。。@AfterReturning:运行结果: {1}

执行过程及源码解析
平时看注解的源码有一个小窍门,跟着源码进去会发现,该注解会实现了什么类,或者注入了某些组件,把注入组件的功能,跟注入的时间点搞清楚了,那么该功能的逻辑就会变得清晰

@EnableAspectJAutoProxy是什么?
@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar

利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetion

internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

给容器中注册一个AnnotationAwareAspectJAutoProxyCreator;

跟着继承树:
AnnotationAwareAspectJAutoProxyCreator->AnnotationAwareAspectJAutoProxyCreator->AspectJAwareAdvisorAutoProxyCreator->AbstractAdvisorAutoProxyCreator->AbstractAutoProxyCreator

通过他的实现可以发现,它是一个后置处理器,并且也是factoryawrae接口的实现类
AnnotationAwareAspectJAutoProxyCreator注册过程

最后老规矩的总结一下(也相当重要!)
@EnableAspectJAutoProxy 开启AOP功能

@EnableAspectJAutoProxy 会给容器中注册一个组件
AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;

容器的创建流程:

registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象

finishBeanFactoryInitialization()初始化剩下的单实例bean

组件创建完之后,判断组件是否需要增强

执行目标方法:

代理对象执行目标方法

CglibAopProxy.intercept();

正常的执行顺序:前置通知-》目标方法-》后置通知-》返回通知

出现异常时:前置通知-》目标方法-》后置通知-》异常通知
?
包括但不限于:分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货面试题集,简历模板等三千多G资料包,关注回复DD无套路免费领取,助您从0到1

原文地址:https://www.cnblogs.com/lvbl/p/12382290.html

时间: 2024-10-02 20:44:08

Spring-AOP注解开发的相关文章

Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解

原创整理不易,转载请注明出处:Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解 代码下载地址:http://www.zuidaima.com/share/1772661373422592.htm 本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifi

Spring AOP 注解配置实例

Spring AOP注解例子 一:导入相关jar包. 首先导入Spring的相关包(这里就不多说了,我这里是3.2.4版本的) 然后导入AOP注解的相关包(不是spring的包)aspectjrt-1.6.7.jar和aspectjweaver-1.6.8.jar和aopalliance.jar (注意这里最好是1.6.7以上的版本,不然容易出错,折腾了我好久,最后才发现是包的版本问题. 所以这里一定要注意,spring 2.0以后的最好是用1.6.7的版本) 二: 建一个class类作为切入面

Spring 模拟注解开发实例

1.注解开发无需导入全新的jar包 l使用注解功能需要导入Spring核心jar包 ?核心jar包(6个) ?spring-beans-3.2.0.RELEASE.jar ?spring-context-3.2.0.RELEASE.jar ?spring-core-3.2.0.RELEASE.jar ?spring-expression-3.2.0.RELEASE.jar ?commons-logging-1.1.1.jar ?log4j-1.2.15.jar 2.使用注解开发必须开启命名空间c

Spring AOP注解方式实现

简介 上文已经提到了Spring AOP的概念以及简单的静态代理.动态代理简单示例,链接地址:https://www.cnblogs.com/chenzhaoren/p/9959596.html 本文将介绍Spring AOP的常用注解以及注解形式实现动态代理的简单示例. 常用注解 @aspect:定义切面 @pointcut:定义切点 @Before:前置通知,在方法执行之前执行 @After:后置通知,在方法执行之后执行 @AfterRunning:返回通知,在方法返回结果之后执行 @Aft

spring AOP注解实现

一.什么是AOP 引用一下维基百科的定义 面向切面的程序设计(Aspect-oriented programming,AOP,又译作面向方面的程序设计.剖面导向程序设计)是计算机科学中的一种程序设计思想,旨在将横切关注点与业务主体进行进一步分离,以提高程序代码的模块化程度.通过在现有代码基础上增加额外的通知(Advice)机制,能够对被声明为"切点(Pointcut)"的代码块进行统一管理与装饰,如"对所有方法名以'set*'开头的方法添加后台日志".该思想使得开发

转:Spring AOP 注解方式实现的一些“坑”

使用过Spring AOP的注解方式实现,也入过不少坑,现在做一下记录,希望有同样需求的朋友可以少走弯路 使用之前还是先过一下官方文档吧,至少可以少走弯路,不用担心英文读不懂,其实只看代码例子就能理解很多问题! 1. SpringBoot如何获得Aspect支持? 看这里:Spring Boot 开启AOP的方法 2. 我按照上面的方法开启了AOP支持,为什么始终是不走切入点方法呢? 首先仔细检查一下,Aspect类是不是少了@Component注解(这一点很重要!),只有一个@Aspect注解

Spring框架学习(三)Spring的注解开发

Spring-注解开发 1.在applicationContext.xml中添加这一句代码能够让IOC容器加载的时候去扫描对应4种注解的类: <context:component-scan base-package="com.bjsxt.tmall"></context:component-scan> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=

spring Aop 注解

个人理解: spring Aop 是什么:面向切面编程,类似于自定义拦截操作,支持拦截之前操作@Before,拦截之后操作@After,拦截环绕操作@Around. 什么情况下使用spring Aop:举例如下 当需要统计某些方法 or 指定xx开头的方法名 or 指定xx结尾的方法名 or 某些类下的方法 or 某些包下的方法 or 所有的方法的耗时统计或添加日志信息时,使用spring Aop 切面编程可以不用修改任何需要统计或添加日志的方法,只需很少一部分代码实现需要做的操作. 某交易系统

Spring aop 注解参数说明

在spring AOP中,需要使用AspectJ的切点表达式语言来定义切点. 关于Spring AOP的AspectJ切点,最重要的一点是Spring仅支持AspectJ切点指示器(pointcut designator)的一个子集. AspectJ指示器 描述 arg() 限制连接点匹配参数为指定类型的执行方法 @arg() 限制连接点匹配参数由指定注解标注的执行方法 execution() 用于匹配是连接点的执行方法 this() 限制连接点匹配AOP代理的Bean引用为指定类型的类 tar

Spring AOP 注解形式

AspectOriented Programing,面向切面编程.   AOP主要用于日志记录,性能统计,安全控制(权限控制),事务处理,异常处理等.将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码.  Spring AOP织入增强(Advice)的方式有两种 如果连接点实现了接口采用jdk自带的动态代理的形式实现织入,如果连接点没有实现接口则采用动态