SpringBoot-AOP
来源:互联网 发布:linux中文字符乱码 编辑:程序博客网 时间:2024/05/18 01:42
SpringBoot-AOP
使用AOP统一处理请求日志
1.AOP的概念
AOP:AOP是一种编程范式,与语言无关,是一种程序设计思想
面向切面(AOP) Aspect Oriented Programming面向对象(OOP) Object Oriented Programming面向过程(POP) Procedure Oriented Programming
面向过程到面向对象:
功能:下雨了,我打开了雨伞面向过程:假如下雨了,我打开了雨伞面向对象:天气-->下雨;我-->打伞
即:换个角度看世界,换个姿势处理问题
面向对象:关注的是将需求功能垂直划分为不同的并且相对独立的,会封装成良好的类并且让他们有属于自己的行为。面向切面:利用横切的技术,将面向对象构建的庞大的类的体系进行水平的切割,并且将其中会影响到多个类的公共行为封装成一个可重用的模块,该模块就成为切面
AOP的思想:将通用的逻辑从业务逻辑中分离出来
2.实现AOP
网络请求和数据库操作请求:
使用AOP思想:
3.实现使用AOP记录每一个http请求
需求:授权访问(必须先登录才能访问)
第一步:添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--项目的基本描述--> <groupId>com.hcx</groupId> <artifactId>girl</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>girl</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--web项目必须引入的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--单元测试时需要用到的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
第二步:编写切面类:
@Aspect@Componentpublic class HttpAspect { //在http请求到方法之前记录 /** * @Before注解:在方法执行之前执行 * com.hcx包下的girlcontroller里面的girlList方法,不管是什么参数都会被拦截 * 所有方法都拦截:execution(public * com.hcx.controller.GirlController.*(..)) */ @Before("execution(public * com.hcx.controller.GirlController.girlList(..))") public void log(){ System.out.println("被拦截了"); } @After("execution(public * com.hcx.controller.GirlController.girlList(..))") public void doAfter(){ System.out.println("我是方法执行之后被拦截"); }}
第三步:拦截controller中的方法:
@RestControllerpublic class GirlController { @Autowired private GirlRepository girlRepository; @Autowired private GirlService girlService; /** * 查询所有女生 * @return */ @GetMapping(value = "/girls") public List<Girl> girlList(){ System.out.println("我是girlList方法"); return girlRepository.findAll(); }}
运行结果:
注意:以上代码可以看出有重复,在切面类中优化:
HttpAspect:
@Aspect@Componentpublic class HttpAspect { private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class); //该类是org.slf4j的 //在http请求到方法之前记录 /** * @Before注解:在方法执行之前执行 * com.hcx包下的girlcontroller里面的girlList方法,不管是什么参数都会被拦截 * 所有方法都拦截:execution(public * com.hcx.controller.GirlController.*(..)) */ /*@Before("execution(public * com.hcx.controller.GirlController.girlList(..))") public void log(){ System.out.println("被拦截了"); }*/ /** * 公用的方法,使用@Pointcut注解 */ @Pointcut("execution(public * com.hcx.controller.GirlController.girlList(..))") public void log(){ } @Before("log()") public void doBefore(){// System.out.println("我是方法执行之前被拦截"); logger.info("前日志信息"); //打印info、error等日志 } @After("log()") public void doAfter(){// System.out.println("我是方法执行之后被拦截"); logger.info("后日志信息"); }}
GirlController:
@RestControllerpublic class GirlController { /** * getLogger方法中的参数与类名对应 */ private final static Logger logger = LoggerFactory.getLogger(GirlController.class); @Autowired private GirlRepository girlRepository; @Autowired private GirlService girlService; /** * 查询所有女生 * @return */ @GetMapping(value = "/girls") public List<Girl> girlList(){// System.out.println("我是girlList方法"); logger.info("我是girlList方法"); return girlRepository.findAll(); }}
记录http请求:
HttpAspect:
@Aspect@Componentpublic class HttpAspect { private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class); //该类是org.slf4j的 /** * 公用的方法,使用@Pointcut注解 */ @Pointcut("execution(public * com.hcx.controller.GirlController.girlList(..))") public void log(){ } @Before("log()") public void doBefore(JoinPoint joinPoint){ /** * 请求路径:url * 请求方式:method * 客户端ip:ip * 请求的是哪个类方法:类方法 * 方法的参数 */ ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest();//注意:选择的HttpServletRequest选的是javax.servlet.http的 //url logger.info("url={}",request.getRequestURL()); //method logger.info("method={}",request.getMethod()); //ip logger.info("ip={}",request.getRemoteAddr()); //getDeclaringTypeName():获取类名,getName:获取类方法 logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); //方法的参数 logger.info("args={}",joinPoint.getArgs()); } @After("log()") public void doAfter(){// System.out.println("我是方法执行之后被拦截"); logger.info("后日志信息"); } /**获取返回的内容: * { "id": 2, "cupSize": "B", "age": 19 } */ @AfterReturning(returning = "object",pointcut = "log()") public void doAfterReturning(Object object){ logger.info("response={}",object.toString()); }}
GirlController:
@RestControllerpublic class GirlController { /** * getLogger方法中的参数与类名对应 */ private final static Logger logger = LoggerFactory.getLogger(GirlController.class); @Autowired private GirlRepository girlRepository; @Autowired private GirlService girlService; /** * 查询所有女生 * @return */ @GetMapping(value = "/girls") public List<Girl> girlList(){// System.out.println("我是girlList方法"); logger.info("我是girlList方法"); return girlRepository.findAll(); }}
Girl:
@Entity //该注解表示该类在数据库中有对应的表 不用创建该表public class Girl { @Id @GeneratedValue private Integer id; private String cupSize; /** * 给年龄加上限制:年龄必须大于18岁 * value:值 * message:提示信息 */ @Min(value =18,message = "年龄必须大于18岁") private Integer age; public Girl() { } @Override public String toString() { return "Girl{" + "id=" + id + ", cupSize='" + cupSize + '\'' + ", age=" + age + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCupSize() { return cupSize; } public void setCupSize(String cupSize) { this.cupSize = cupSize; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }}
阅读全文
0 0
- springboot-AOP
- SpringBoot-AOP
- springBoot aop
- springboot-aop访问拦截
- Springboot配置aop
- 第四十章 SpringBoot AOP
- springboot集成AOP
- springboot使用AOP
- SpringBoot aop demo
- SpringBoot-10整合AOP
- springboot之AOP配置
- springboot-AOP
- SpringBoot-AOP处理请求
- SpringBoot(五):aop
- Springboot与Aop
- SpringBoot+Gradle实现AOP
- springboot 集成aop
- SpringBoot中aop的使用
- Mean-shift超像素分割
- 使用启发式算法生成初始解输入Gurobi 中求解
- Java_14 Class类与Java反射
- mybatis源码解析
- PAT 乙级 1001
- SpringBoot-AOP
- Quartz定时调度器02
- 深度优先搜索———全排列
- java每日一练
- 二叉搜索树实现与深度优先遍历和广度优先遍历
- C语言错误代码释义大全,你值得拥有!
- js中将字符数组转为数值数组
- shell for循环编程
- hdu 3951 Coin Game