1、导入依赖aop依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>4.3.12.RELEASEversion>
dependency>
2、 定义业务逻辑类 ;在业务逻辑执行的时候进行日志打印(方法执行之前,方法运行结束,异常,返回 …)
3、日志切面类:切面类里面的方法需要动态的感知业务类方法运行到哪一步了
4、通知方法
前置通知(@Before)
:在目标方法执行之前执行后置通知(@After)
:在目标方法运行结束之后执行返回通知(@AfterReturning)
:在目标方法正常返回之后运行异常通知(@AfterThrowing)
:在目标方法运行出现异常以后运行环绕通知(@Around)
:动态代理,手动推进方法运行5、 给切面类的目标方法标注运行时机(通知注解)
6、将切面类和目标类都加入到容器中
7、必须告诉spring哪个类是切面类(给切面类加上注解:@Aspect)
8、给配置 类加上@EnableAspectJAutoProxy(开启基于注解 aop模式)
代码示例
业务类
public class MathCalculator {
public int div(int i, int j) {
return i/j;
}
}
日志切面类
/**
* 切面类
*/
@Aspect
public class LogAspects {
@Pointcut("execution(public int com.fyj.spring.annotation.aop.MathCalculator.*(..))")
public void pointCut() {}
@Before("pointCut()")
public void logStart(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
List<Object> list = Arrays.asList(joinPoint.getArgs());
System.out.println(name + "运行开始。。。参数列表是:{"+list+"}");
}
@After("pointCut()")
public void logEnd(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
List<Object> list = Arrays.asList(joinPoint.getArgs());
System.out.println(name + "除法运行结束 。。。参数列表是:{"+list+"}");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void logReturn(JoinPoint joinPoint, Object result) {
System.out.println(joinPoint.getSignature().getName() + "除法正常返回 。。。运行结果:{"+result+ "}");
}
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void logException(JoinPoint joinPoint, Exception exception) {
System.out.println(joinPoint.getSignature().getName() + "异常 。。。异常信息:{"+exception.getMessage()+"}");
}
}
配置类
@Configuration
@EnableAspectJAutoProxy
public class MyConfigration {
@Bean
public MathCalculator mathCalculator () {
return new MathCalculator();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
测试类
public class MyTest {
@Test
public void test01 () {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigration.class);
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(1, 1);
// mathCalculator.div(1, 0);
}
}
分析Spring AOP原理从@EnableAspectJAutoProxy
开始
@EnableAspectJAutoProxy 导入了 AspectJAutoProxyRegistrar 这个类
@EnableAspectJAutoProxy
是什么?@Import(AspectJAutoProxyRegistrar.class),给容器中导入AspectJAutoProxyRegistrar
- 利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetion
internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
第一步就是给容器中注册一个AnnotationAwareAspectJAutoProxyCreator
;
AnnotationAwareAspectJAutoProxyCreator
在IOC容器的创建过程中,会先实例化 BeanPostProcessors,而 AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessors ,继承树如下:
AnnotationAwareAspectJAutoProxyCreator 继承树如下:
> AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory
AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.有后置处理器的逻辑;
AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory()
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
IOC容器中BeanPostProcessors 创建过程
即 AnnotationAwareAspectJAutoProxyCreator 的创建,
AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessors
以上是创建和注册AnnotationAwareAspectJAutoProxyCreator
的过程
每一个bean创建之前,调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation();方法
创建代理对象 ,调用AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法