AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
下面已登录为例。登录时需要做项目验证为例子记录下AOP的实现。
1.首先我们定义下切点注解类;
@Target(ElementType.METHOD)//表示用于标识方法
@Retention(RetentionPolicy.RUNTIME)//表示运行时保留
public @interface ProjectValid {
/** 校验类型*/
public ProjectValidType validType();
/**登陆名*/
public String loginName() default "";
}
2.定义切面类:
@Aspect
@Component
public class ProjectAopValid {
private static final Logger logger = LoggerFactory.getLogger(ProjectAopValid.class);
@Autowired
private BfsProjectService projectService;
@Pointcut("@annotation(com.zeei.bfs.project.valid.ProjectValid)")
public void projectAspect() {
}
@Before("projectAspect()")
public void before(JoinPoint joinPoint) {
Class<? extends Object> clazz = joinPoint.getTarget().getClass();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
Method[] methods = clazz.getMethods();
if (ArrayUtils.isNotEmpty(methods)) {
// 获取方法的注解
ProjectValid validAnno = Stream.of(methods).filter(s -> StringUtils.equals(methodName, s.getName()))
.map(s -> s.getAnnotation(ProjectValid.class)).findFirst().get();
if (ArrayUtils.isNotEmpty(methods)) {
// 获取方法的注解
ProjectValid validAnno = Stream.of(methods).filter(s -> StringUtils.equals(methodName, s.getName()))
.map(s -> s.getAnnotation(ProjectValid.class)).findFirst().get();
ProjectValidType validType = validAnno.validType();
//具体业务处理方法
String result = validInfo(validType, args);
if (!StringUtils.equals("0", result)) {
logger.info(">>>>>>>>>>>项目校验失败:{}", result);
// 通过抛出异常方式停止
throw new ProjectValidException(result);
}
}
logger.info(">>>>>>>>>>>>>>>>>>>>>>项目校验成功");
}
3.定义切点参数类
public enum ProjectValidType {
/**
* 校验登陆
*/
validLogin,
/**校验项目用户数量*/
validUserNumber,
/**校验项目站点分配时数量*/
validPointDistribute,
/**校验站点创建*/
validPointCreate
}
4.绑定切点到触发的业务方法上
/**
* login:系统登录
*
* @param userName
* 用户名info/get
* @param password
* 密码
* @param loginTimes
* 同一台设备登录的次数(2:表示同一台设备登录两次,属于异常情况,需要登出)
* @return ResultBasicVO
*/
@ProjectValid(validType=ProjectValidType.validLogin)
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public ResultLoginVO login(String userName, String password, String loginTimes, HttpServletResponse response,
String loginMode, String verifyCode) {
logger.info("执行业务方法!")
}
5.细节参照:[https://blog.csdn.net/weixin_43128990/article/details/107005062]