[#0x0044] Spring AOP学习(3):例子与基本概念

[#0x0044] Spring AOP学习(三):例子与基本概念

  依旧是LogInterceptor的例子。下面是beans.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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
	<context:annotation-config />
	<context:component-scan base-package="com.bjsxt"/>
 	<aop:aspectj-autoproxy />
</beans>

注意添加aop的namespace和<aop:aspectj-autoproxy />这一句。LogInterceptor的代码如下:

package com.bjsxt.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogInterceptor {
	@Pointcut("execution(public * com.bjsxt.service..*.add(..))")
	public void myMethod(){};
	
	@Before("myMethod()")
	public void before() {
		System.out.println("method before");
	}
	
	@Around("myMethod()")
	public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("method around start");
		pjp.proceed();
		System.out.println("method around end");
	}
	
}

这里需要注意两点:

  (1) 这里必须要有@Component,让Spring来new一个LoginInterceptor对象(我们定义了<context:component-scan base-package="com.bjsxt"/>来让Spring来扫描com.bjsxt包;扫描到@Aspect就知道要织入这个类了)。这样才能把LoginInterceptor对象织入UserDAOImpl

  (2) execution(public void com.bjsxt.dao.UserDAOImpl.save(com.bjsxt.model.User)"),这是AspectJ语法,execution表示在方法执行时切入。另有其他的切入点,比如属性初始化时、类加载时

 

  根据这个例子,我们来理解一些AOP的概念

  (1) Target: UserDAOImpl是织入的Target

  (2) JoinPoint: "execution(public void save())"这里就是JoinPoint,即切入点

  (3) Advice: before()方法是Advice,Advice is an action taken by an Aspect at a certain JoinPoint

  (4) AdviceType: @Before是AdviceType,表示这是一个Advice that executes before a JoinPoint

  (5) PointCut: 从通配符(@Pointcut("execution(public * com.bjsxt.service.*.add(.))"))可以看出,PointCut是JoinPoint的集合,但是注意PointCut必须依赖于一个方法

  (6) Aspect: LogInterceptor这个类,或者说LogInterceptor这个类的逻辑(即记录日志)是一个Aspect