AOP在Java项目中使用实例
AOP在实际使用时关注什么
- 不需要关注你要用的是jdk动态代理还是CGLIB,spring在底层会自动选择,不用考虑目标对象是不是接口
- 如果是SSM项目,那在写配置文件的时候要注意启动aop的配置标签要写在spring-mvc.xml 中,不要写到ApplicationContext.xml或者其他的配置文件中,否则就可能切面不生效。ssm项目目录结构请看如下博客。链接: 链接
- aop可以和自定义注解一起使用。比如说自定义增强日志功能等。和注解一起使用的情况可以这么理解,在哪加注解,哪就是切点。
- 通知的执行顺序:
![**加粗样式**](https://i-blog.csdnimg.cn/blog_migrate/05eee68a4e9ed5b5c6e577aabc77d6b5.png)
- 切点表达式的用法用到时查一下就可以了,在这里不详细介绍,如有需求自行百度。
操作步骤
aop在ssm中的使用
- 导入依赖,在项目中加入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
- 修改配置文件(修改spring-mvc.xml)
<!--启动aop-->
<aop:aspectj-autoproxy />
<!--指定扫描范围-->
<context:component-scan base-package="com.xxx.扫描范围"></context:component-scan>
- 创建切面类,编写切面相关代码
@Aspect
@Component
public class LoginRenewalAspect {
//这个地方指定切点表达式,如果直接指点切点,用execution();如果使用自定义注解那么用@annotation()
@Pointcut("execution(* com.xxx.xxx.modules..*Controller.*(..))")
//@Pointcut("@annotation(com.xxx.xxx.aspect.注解名)")
private void pointcut() {
}
//SpringAOP中,通过advice定义横切逻辑,Spring支持的5中类型的Advice 通知类型 连接点
//实现接口
//前置通知 方法前 org.springframework.aop.MethodBeforeAdvice
//后置通知 方法后 org.springframework.aop.AfterReturningAdvice
//环绕通知 方法前后 org.springframework.aop.MethodInterceptor
//异常抛出通知 方法抛出异常 org.springframework.aop.ThrowsAdvice
//引介通知 类中增加新的方法属性 org.springframework.aop.IntroductionInterceptor
//此处用后置通知举例。
@After("pointcut()")
public void After() {
//增强的业务逻辑。。。。。
}
}
- 启动项目,启动项目后调用目标对象的方法会在此基础执行增强方法。
aop在spring boot中的使用(aop + 注解 的方式实现)
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 创建自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginRenewal {
String value() default "";
}
- 创建切面类,编写切面相关代码
@Aspect
@Component
public class LoginRenewalAspect {
//这个地方指定切点表达式,如果直接指点切点,用execution();如果使用自定义注解那么用@annotation()
@Pointcut("@annotation(com.xxx.xxx.aspect.LoginRenewal )")
private void pointcut() {
}
//此处用前置通知举例。
@Before("pointcut()")
public void Before() {
//增强的业务逻辑。。。。。
}
}
- 在目标对象的方法上面加上自定义的注解
@RestController
@RequestMapping("/aop")
public class AopController {
@GetMapping("/testHello")
@LoginRenewal
public String testHello(String params){
return "Hello World";
}
}
- 重启项目,访问该请求,会执行增强后的方法。