SpringAop应用之日志

1、ApringAop

       AOP(Aspect Oriented Programming),即面向切面编程。可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。  实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

2、AOP使用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用

Authentication 权限

Caching 缓存

Context passing 内容传递

Error handling 错误处理

Lazy loading 懒加载

Debugging 调试

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Performance optimization 性能优化

Persistence 持久化

Resource pooling 资源池

Synchronization 同步

Transactions 事务

3、AOP核心概念

(1)、横切关注点

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

(2)、切面(aspect)

类是对物体特征的抽象,切面就是对横切关注点的抽象

(3)、连接点(joinpoint)

被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

(4)、切入点(pointcut)

对连接点进行拦截的定义

(5)、通知(advice)

所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

(6)、目标对象

代理的目标对象

(7)、织入(weave)

将切面应用到目标对象并导致代理对象创建的过程

(8)、引入(introduction)

在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

4、应用之日志

      这个里主要对所有方法进行前置处理,后置处理,记录日志,采用注解方式实现日志处理场景。

(1)依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
	 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

(2)定义切点切面,详见代码

package cn.king.boot.aop;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.JoinPoint.StaticPart;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.SourceLocation;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class LogAspect {
	@Pointcut(value = "execution(* cn.king.boot.controller.TestController.*(..))")
	public void log() {
    System.err.println("切点");
	}
	@Before(value = "log()")
	public void beforeLog(JoinPoint joinPoint) {
		System.err.println("----------------------------------------");
		System.err.println("前置通知=======》》》");
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		StringBuffer url = request.getRequestURL();
	    //请求方法
		String method = request.getMethod();
		//ip地址
		String ip = request.getRemoteAddr();
		//
		String className = joinPoint.getTarget().getClass().getName();
		//方法
		String methodName = joinPoint.getSignature().getName();
		//参数
		Object[] args = joinPoint.getArgs();
		//切点
		String kind = joinPoint.getKind();
		//切面
		SourceLocation sourceLocation = joinPoint.getSourceLocation();
		StaticPart staticPart = joinPoint.getStaticPart();
		System.err.println("url:"+url);
		System.err.println("请求方式:"+method);
		System.err.println("ip:"+ip);
		System.err.println("类路径:"+className);
		System.err.println("方法名:"+methodName);
		System.err.println("参数:"+Arrays.toString(args));
		System.err.println("切点方法名:"+kind);
		System.err.println("本地资源:"+sourceLocation);
		System.err.println("切面::"+staticPart);
		System.err.println("------------------------------------------");

	}
	@AfterReturning(value = "log()", returning = "obj")
	public void afterReturningLog(JoinPoint joinPoint,Object obj) {
		System.err.println("后置通知=======》》》");
		String returnResult = obj.toString();
		System.err.println("返回结果:"+returnResult);
	}
}

(3)控制层

@RequestMapping(value = "/aop")
	public JSONObject json(String a,String b) {
		System.err.println("控制层==="+a+"---"+b);
		JSONObject json = jsonService.json(a, b);
		return json;
		
	}

(4)Console

2019-04-23 22:45:12.575  INFO 21116 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-04-23 22:45:12.778  INFO 21116 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-04-23 22:45:13.847  INFO 21116 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2019-04-23 22:45:14.003  INFO 21116 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2019-04-23 22:45:14.017  INFO 21116 --- [           main] cn.king.boot.SpringFirstApplication      : Started SpringFirstApplication in 10.8 seconds (JVM running for 11.686)
------__-----
2019-04-23 22:45:20.823  INFO 21116 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-04-23 22:45:20.823  INFO 21116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2019-04-23 22:45:20.871  INFO 21116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 47 ms
----------------------------------------
前置通知=======》》》
url:http://127.0.0.1:8080/aop
请求方式:POST
ip:127.0.0.1
类路径:cn.king.boot.controller.TestController
方法名:json
参数:[a, b]
切点方法名:method-execution
本地资源:org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@cf2c893
切面::execution(JSONObject cn.king.boot.controller.TestController.json(String,String))
------------------------------------------
控制层===a---b
a:a           b:b
后置通知=======》》》
返回结果:{"a":"a","b":"b"}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值