Sometimes we may think about how to do something before the method runs
有时我们会想,如何在一些方法执行前或者执行后做一些操作
比如日志的记录、权限的鉴定等等
昨天,我们搭建了个简单的spring
项目并写了几个接口
其中一个是这样的
这里返回给前端的map
中的data
,我是手动加的前缀"服务器对你说"
我们现在来用AOP
实现
先修改我们接口中的代码,去掉前缀
然后配置AOP
|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| hljs xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <!-- 配置包扫描器,扫描@Controller注解的类 --> <context:component-scan base-package="com.ruben.controller"/> <!-- 配置注解驱动 --> <mvc:annotation-driven/> <mvc:default-servlet-handler/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 配置资源映射 --> <mvc:resources location="/static/" mapping="/static/**"/> <!-- 激活组件扫描功能,在包"com.example.aop及其子包下面自动扫描通过注解配置的组件--> <context:component-scan base-package="com.ruben.aop"/> <!-- 启动AspectJ支持 只对扫描过的bean有效--> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>
|
然后创建我们的aop
包
在aop
包创建一个类,并加上注解
定义我们的切入点,也就是需要被织入的位置
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7
| hljs java /** * 指定say方法 */ @Pointcut("execution(* com.ruben.controller.UserController.say(..))") private void pointcut() { }
|
然后编写我们的切面
|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12
| hljs java /** * 返回前对参数进行处理,加上前缀 * @param point * @param returnValue */ @AfterReturning(pointcut = "pointcut()", returning = "returnValue") public void addPrefix(JoinPoint point, Object returnValue) { if (returnValue instanceof HashMap) { Map<String, Object> result = (Map<String, Object>) returnValue; result.put("data", "achao对你说:" + result.get("data")); } }
|
完整代码
|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| hljs java package com.ruben.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; /** * @ClassName: SayWordAop * @Description: 说话Aop * @Date: 2020/8/7 19:36 * * * @author: achao<achao1441470436 @ gmail.com> * @version: 1.0 * @since: JDK 1.8 */ @Aspect @Component public class SayWordAop { /** * 指定say方法 */ @Pointcut("execution(* com.ruben.controller.UserController.say(..))") private void pointcut() { } /** * 返回前对参数进行处理,加上前缀 * @param point * @param returnValue */ @AfterReturning(pointcut = "pointcut()", returning = "returnValue") public void addPrefix(JoinPoint point, Object returnValue) { if (returnValue instanceof HashMap) { Map<String, Object> result = (Map<String, Object>) returnValue; result.put("data", "achao对你说:" + result.get("data")); } } }
|
然后启动我们的项目,发现切面生效了
发送的参数为登录成功!
但是返回的结果是
说明我们的切面生效了,我们顺便把其他几种也加上吧
比如加个校验
|---------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| hljs java /** * 登录参数校验 * * @param point * @return * @throws Throwable */ @Around("execution(* com.ruben.controller.UserController.login(..))") public Object permissionCheck(ProceedingJoinPoint point) throws Throwable { List<Object> paramList = Arrays.asList(point.getArgs()); AtomicBoolean passValidate = new AtomicBoolean(true); String pattern = "^[A-Za-z0-9]{4,40}$"; AtomicReference<String> errorMsg = new AtomicReference<>("您输入的参数格式有误"); paramList.forEach(param -> { User user = (User) param; if (!Pattern.matches(pattern, user.getUsername())) { errorMsg.set("用户名格式错误"); passValidate.set(false); } else if (!Pattern.matches(pattern, user.getPassword())) { errorMsg.set("密码格式错误"); passValidate.set(false); } }); if (!passValidate.get()) { Map<String, Object> map = new HashMap<>(1 << 2); map.put("success", false); map.put("code", -629); map.put("msg", errorMsg.get()); return map; } return point.proceed(); }
|
还比如在方法执行前后记录日志
先加上注解
然后修改配置文件
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9
| hljs xml <!-- 配置log4j日志 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/config/log4j.properties</param-value> </context-param> <!--log4j日志监听 --> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener>
|
添加配置文件
|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| hljs properties #log4j properties file #log4j.rootLogger = [level],appenderName,appenderName2,... log4j.rootLogger=INFO,console,file #console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-22d{yyyy/MM/dd HH:mm:ss}%m%n #file log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=./logs/project.log log4j.appender.file.Append=true log4j.appender.file.Encoding=UTF-8 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
|
就可以用log.info()
打印日志啦!
|------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| hljs java /** * 在com.ruben包下任意方法执行前打印日志 * * @param point */ @Before(value = "execution(* com.ruben.*.*.*(..))") public void logRecode(JoinPoint point) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); log.info("==>url:" + request.getRequestURI()); log.info("==>参数:" + Arrays.toString(point.getArgs())); } /** * 在com.ruben.controller包下任意方法执行后打印 * * @param point */ @After("execution(* com.ruben.controller.*.*(..))") public void recodeWord(JoinPoint point) { log.info("<==" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName() + "方法执行结束"); }
|
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| hljs shell 2020/08/07 22:00:11 ==>url:/user/login 2020/08/07 22:00:11 ==>参数:[User(username=achao, password=ruben)] 2020/08/07 22:00:11 <==com.ruben.controller.UserController.login方法执行结束 2020/08/07 22:00:11 ==>url:/user/say 2020/08/07 22:00:11 ==>参数:[登录成功!] 2020/08/07 22:00:11 <==com.ruben.controller.UserController.say方法执行结束
|