零、AOP
面向切面编程。把多个模块具有相同实现细节的功能提取出来作为一个切面(目的是实现复用),实现切面和业务逻辑的分离(优势)。
1.为什么不用继承或者委托?
继承可能导致不好的对象体系:继承表示is-a关系,使用继承复用通用功能可能导致尴尬的子父类关系。使用委托可能需要委托对象进行复杂的调用。
2.Spring AOP
- 构建在动态代理基础之上,所以Spring对AOP的支持局限于方法拦截。
- Spring在运行时才创建代理对象。
3.Spring中AOP如何实现?
- Spring AOP封装了
- JDK动态代理(优先):基于接口(代理类和被代理类需要实现一个相同接口)
- CGLIB代理:可对任意类进行代理(基于继承,所以被代理类不能被final修饰;基于实现)
一、AOP相关名词解释
1.Target:目标对象,被代理的对象
2.JoinPoint:连接点,目标对象中可被增强的方法
3.PointCut:切入点,目标对象中已被增强的方法
4.Advice:增强or通知,增强的代码
5.Weaving:织入,将Advice应用到PointCut的过程
6.Proxy:代理,将Advice织入目标对象后,形成的代理对象
7.Aspect:切面,即切入点+通知
二、Spring AOP使用
注解方式
@Aspect //切面 @Component //POJO,交给Spring管理 public class LoggerAspect { private final Logger log= LoggerFactory.getLogger(LoggerAspect.class); //xiang方法是一个标识方法,代表可重用切入点表达式 @Pointcut("execution(* com.xiang.*.*.*(..))") public void xiang(){}; @Before("xiang()") public void beforeMethod(JoinPoint joinPoint){ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if(requestAttributes!=null){ HttpServletRequest request = requestAttributes.getRequest(); //打印请求内容 log.info("===============请求内容Start==============="); log.info("请求地址:"+request.getRequestURL().toString()); log.info("请求方式:"+request.getMethod()); log.info("请求类方法:"+joinPoint.getSignature()); log.info("请求类方法参数:"+ Arrays.toString(joinPoint.getArgs())); log.info("请求时间:"+ String.format("%tc",new Date())); log.info("===============请求内容End==============="); } } }
注:
execution(* cglibproxy.Student.*(..))表示对Student对象的public的,返回值类型不限的,方法名不限的,参数不限的 方法进行增强。