零、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的,返回值类型不限的,方法名不限的,参数不限的 方法进行增强。