1 AOP 入门
1.1 AOP概念
面向切面编程,指程序在运行期间动态的将某段代码切入到指定方法位置进行运行的编程方式
1.2 AOP通知方法
前置通知: logStart(),在目标方法(div)运行之前运行 (@Before)
后置通知:logEnd(), 在目标方法(div)运行结束之后运行,无论正常或异常结束 (@After)
返回通知:logReturn, 在目标方法(div)正常返回之后运行 (@AfterReturning)
异常通知:logException, 在目标方法(div)出现异常后运行(@AfterThrowing)
环绕通知:动态代理, 最底层通知,手动指定执行目标方法(@Around)
执行顺序:AroundStart Before AroundEnd After Returing
1.3 demo
(1) pom
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
</dependencies>
(2) 配置文件
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.spring")
public class SpringConfig {
}
(3) 切面类
@Configuration
@Aspect
public class SpringAspects {
/**
* 声明切点
*/
@Pointcut("execution(public int com.spring.service.*.*(..))")
public void pointCut() {
}
/**
* 前置通知
*/
@Before("pointCut()")
public void before(JoinPoint joinPoint) {
System.out.println("@Before:" + joinPoint.getSignature().getName()+" "+ Arrays.asList(joinPoint.getArgs()));
}
/**
* 后置通知
*/
@After("pointCut()")
public void after() {
System.out.println("@After:");
}
/**
* 返回通知
*/
@AfterReturning(value = "pointCut()", returning = "result")
public void returing(Object result) {
System.out.println("@AfterReturning:" + result);
}
/**
* 异常通知
*/
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void throwing(Exception exception) {
System.out.println(" @AfterThrowing:" + exception);
}
/**
* 环绕通知
*/
@Around("pointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("@Around start ");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("proceed: " + proceed);
System.out.println("@Around end");
return proceed;
}
}
(4) service
package com.spring.service;
import org.springframework.stereotype.Service;
@Service
public class CalculatorService {
public int div(int i, int j) {
return i / j;
}
}
(5) 启动类
public class SpringApplicationContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringConfig.class);
CalculatorService calculatorService = (CalculatorService) applicationContext.getBean("calculatorService");
calculatorService.div(5, 1);
applicationContext.close();
}
}
2 @EnableAspectJAutoProxy 的作用
(1) 源码分析,引入了AspectJAutoProxyRegistrar类
(2)AspectJAutoProxyRegistrar作用分析
AspectJAutoProxyRegistrar作用其实就是给IOC中添加AnnotationAwareAspectJAutoProxyCreator.class(name为,org.springframework.aop.config.internalAutoProxyCreator)
3、AOP 核心类分析 AnnotationAwareAspectJAutoProxyCreator
3.1、AnnotationAwareAspectJAutoProxyCreator类关系图
(1)、InstantiationAwareBeanPostProcessor:实现了BeanPostProcessor后置处理器。
(2)、Ordered:IOC初始化时,具有高优先级。
3.2、AbstractAutowireCapableBeanFactory docreate方法打断点调试
(1) F8一直调到BeanName为org.springframework.aop.config.internalAutoProxyCreator
(2) 查看调用方法
(3) 定位到AbstractApplicationContext refresh()方法里面,在registerBeanPostProcessors实现了AOP的Bean的注入。
4 PostProcessorRegistrationDelegate registerBeanPostProcessors方法作用
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//1 获取所有BeanPostProcessor接口的实现类beanname
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//2 priorityOrderedPostProcessors,类型为PriorityOrdered.class的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//3 存储类型为Ordered.class 和 noneOrder类型的Bean名称
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//4 把 PriorityOrdered.class、Ordered.class、noOrder.class三种类型分开
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//5 排序,并且注册PriorityOrdered.class类型的到IOC中
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//6 创建并且把类型为Order.class的BeanPostProcessor存储起来
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
/**
* AOP核心类AnnotationAwareAspectJAutoProxyCreator,实现了Order接口,在此通过
* getBean->doGetBean->createBean->doCreateBean.......创建且加入到IOC中
*/
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//7 Order.class类型的BeanPostProcessor进行排序并且注册到IOC中
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//8 创建并且把noOrder类型的BeanPostProcessor存储起来
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//9 排序、注册,nonOrderedPostProcessors类型的Bean
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
5 calculateService加强过程
(1) AbstractAutowireCapableBeanFactory initializeBean 打断点找到CalculatorService的Bean,看是在前置加强还是在后置加强
(2) 首先找到前置处理器,发现前置处理器没有增强类
(3) 后置处理器
跟进去发现是后置处理器增强了bean
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15157.html