Spring boot面向切面编程AOP与自定义注解

spring最核心的两个功能是aop和ioc,即面向切面,控制反转。本文简单探讨下核心功能之一的aop。

一、AOP是什么?

aop全称Aspect Oriented Programming面向切面,AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

简单的说,就是提供一个为一个业务实现提供切面注入的机制,通过这种方式,在业务运行中将定义好的切面通过切入点绑定到业务中,以实现将一些特殊的逻辑绑定到此业务中。

二、AOP编程中的基本概念

1.切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式或者基于@Aspect注解的方式来实现。

2.连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。

3.通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。

4.切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。

三、Spring boot使用AOP编程,实现日志记录功能

1.首先,pom文件引入aop依赖

org.springframework.boot spring-boot-starter-aop 2.定义自定义注解

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default “”;
}
首先利用@interface来声明该类为接口类,用@Target来声明该注解的作用范围。其中ElementType.METHOD, ElementType.TYPE表明该注解作用范围是方法和类。@Retention注明该注解的作用周期。RetentionPolicy.RUNTIME表明该注解在运行时也是有效的。

3.定义切面类

@Aspect
@Component
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;

@Pointcut("@annotation(io.sirc.common.annotation.SysLog)")
public void logPointCut() { 
	
}

@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
	long beginTime = System.currentTimeMillis();
	//执行方法
	Object result = point.proceed();
	//执行时长(毫秒)
	long time = System.currentTimeMillis() - beginTime;
	Signature signature = point.getSignature ();
	String s = signature.toString ();
	//保存日志
	saveSysLog(point, time);
	return result;
}

private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
	MethodSignature signature = (MethodSignature) joinPoint.getSignature();
	Method method = signature.getMethod();

	SysLogEntity sysLog = new SysLogEntity();
	SysLog syslog = method.getAnnotation(SysLog.class);
	if(syslog != null){
		//注解上的描述
		sysLog.setOperation(syslog.value());
	}

	//请求的方法名
	String className = joinPoint.getTarget().getClass().getName();
	String methodName = signature.getName();
	sysLog.setMethod(className + "." + methodName + "()");
	String login ="login";
	//请求的参数
	Object[] args = joinPoint.getArgs();
	try{
		String params = new Gson().toJson(args);
		sysLog.setParams(params);
		if(methodName.equals (login))
		{
			SysLoginForm arg = (SysLoginForm) args[0];
			sysLog.setUsername (arg.getUsername ());
		}
	}catch (Exception e){

	}

	//获取request
	HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
	//设置IP地址
	sysLog.setIp(IpUtils.getIpAddr(request));

	//用户名
	String username=null;
	if(!methodName.equals (login)){
		username= ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();

	sysLog.setUsername(username);
	}
	sysLog.setTime(time);
	sysLog.setCreateDate(new Date());
	sysLog.setId (UUID.randomUUID ().toString ());
	//保存系统日志
	sysLogService.save(sysLog);
}

}
该代码是实现注解切片逻辑的代码即保存日志代码。其中@Aspect用来声明切片的实现,只是其中@annotation表明该切片作用范围为声明的注解作用范围。

需要注意的是,:当定义了一个切面: 即一个方法被一个aspect类拦截,aspect类内部的 advice 将按照以下的顺序进行执行: image

4.自定义注解使用

/**
* 修改登录用户密码
*/
@SysLog(“修改密码”)
@PostMapping("/password")
public Result password(@RequestBody PasswordForm form){
\\\
}
直接在Controller层,加入自定义的注解,程序运行时会因为AOP定义的切点,进入切面完成当前操作的日志记录。同时又不影响原业务的运行。

四、总结

AOP面向切面编程,把散落在程序中的公共部分提取出来,做成切面类,这样的好处在于,代码的可重用,一旦涉及到该功能的需求发生变化,只要修改该代码就行。就像日志等、业务量大时,用户的每个操作都是需要日志记录,将这块内容独立写在切面中,采用AOP思想显得简单和方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中使用AOP自定义注解可以帮助我们更方便地进行方法的拦截和处理。下面是一种最佳实践过程: 1. 首先,我们需要引入`spring-boot-starter-aop`依赖。可以在`pom.xml`文件中添加如下内容: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 2. 创建一个自定义注解。可以使用`@interface`关键字创建一个注解类,并在注解类中定义需要的属性。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { // 定义需要的属性 } ``` 3. 创建一个切面类。切面类用来定义需要进行拦截和处理的方法。可以使用`@Aspect`注解标记该类,并使用`@Around`注解指定要拦截处理的目标方法。例如: ```java @Aspect @Component public class MyAspect { @Around("@annotation(com.example.MyAnnotation)") public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable { // 在方法执行前进行处理 // ... Object result = joinPoint.proceed(); // 在方法执行后进行处理 // ... return result; } } ``` 4. 在Spring Boot的启动类上添加`@EnableAspectJAutoProxy`注解,开启AOP的支持。例如: ```java @SpringBootApplication @EnableAspectJAutoProxy public class Application { // ... } ``` 5. 在需要应用切面的方法上添加自定义注解。 ```java @MyAnnotation public void someMethod() { // ... } ``` 通过以上步骤,我们就可以成功地在Spring Boot中使用AOP自定义注解来进行方法的拦截和处理了。需要注意的是,如果定义的注解只用于标记方法,而不需要定义属性,可以简化为一个空接口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值