spring 注解学习 五 Aop使用
五、spring注解版学习 Aop的使用
5.1、spring Aop使用示例
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
2、在配置类中开始Aop自动代理
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Aop:【动态代理】
* 在程序运行期间动态的将一段特定的代码插入到特定方法的特定位置进行运行的编程方式
*/
@Configuration
@EnableAspectJAutoProxy//开始Aop的自动的代理
@ComponentScan("com.*.*")
public class AopConfig {
}
3、定义业务逻辑类
import org.springframework.stereotype.Component;
@Component
public class MathCalculator {
public int div(int x,int y) {
System.out.println("方法运行了");
return x/y;
}
}
4、定义切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LogAspects {
//抽取公共的切入点表达式
@Pointcut("execution(public * com.xxxx.aop.MathCalculator.*(..))")
public void pointCut() {
}
@Before("execution(public * com.xxxx.aop.MathCalculator.*(..))")
public void logStart(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();//获取被拦截方法的参数
Signature signature = joinPoint.getSignature();//获取被拦截方法的签名
String name = signature.getName();
System.out.println(name);
System.out.println("除法运行");
}
@After("pointCut()")
public void logEnd() {
System.out.println("除法结束");
}
@AfterReturning("pointCut()")
public void logReturn() {
System.out.println("除法正常返回");
}
@AfterThrowing("pointCut()")
public void logException() {
System.out.println("除法异常");
}
}
通过JoinPoint参数可以获取到被拦截方法传入的参数
5.2、Aop原理
1、@EnableAspectJAutoProxy注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)//导入AspectJAutoProxyRegistrar中注入的bean
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar类是实现了ImportBeanDefinitionRegistrar接口的类,详情请参考Import注解的作用
@EnableAspectJAutoProxy注解的作用就是把org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 注入到spring容器中,并且bean的名字叫org.springframework.aop.config.internalAutoProxyCreator
2、AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator实现了 SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware。