AOP是使用动态代理而现实的,在上面动态代理中,我们可以想一下几个概念,我们写一个验证方法,在现实类中我们在拿几个方法中应用这个方法。那在Spring AOP中是如何表述这些概念?
下面先来看AOP中几个比较重要的概念:
² 切面(Aspect)
切面,对象操作过程中的截面。这可能是AOP中最关键的一个术语。例如,我们上面介绍的用户权限验证,不同身份的用户可以做什么,不可以做什么,均由这个模块加以判定。而这个模块调用的位置通常也比较固定:用户发起请求之后,执行业务逻辑之前。
² 连接点(JoinPoint)
程序运行过程中的某个阶段点。如某个方法调用,或者某个异常被抛出。
² 处理逻辑(Advice)
在某个连接点所采用的处理逻辑,处理逻辑的调用模式通常有三种:
1. Around
在连接点前后插入预处理过程和后处理过程。
2. Before
仅在连接点之前插入预处理过程。
3. Throw
在连接点抛出异常时进行异常处理。
² 切点(PointCut)
一系列连接点的集合,它指明处理方式(Advice)将在何时被触发。
1.1. 采用注解配置的方式实现AOP
下面我们来介绍一个用注解库来实现spring AOP,来讲解AOP相关概念。
步骤:
1) 添加spring相关依赖库
* SPRING_HOME/dist/spring.jar
* SPRING_HOME/lib/jakarta-commons/commons-logging.jar
* SPRING_HOME/lib/log4j/log4j-1.2.14.jar
* SPRING_HOME/lib/aspectj/*.jar
2) 采用Aspect定义切面
3) 在Aspect定义Pointcut和Advice
4) 启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中
例子我们还是基于上面动态代理的那个例子,代码如下:
使用注解配置AOP类,SecurityHandler.java
/**
* 定义Aspect
*/
@Aspect
public class SecurityHandler {
/**
* 定义Pointcut,Pointcut的名称就是allAddMethod,
* 此方法不能有返回值和参数,该方法只是一个
* 标识
* Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint)
*/
@Pointcut("execution(* add*(..)) || execution(* del*(..))")
private void allAddMethod(){};
/**
* 定义Advice,标识在那个切入点何处织入此方法
*/
@Before("allAddMethod()")
private void checkSecurity() {
System.out.println("------checkSecurity()------");
}
}
applicationContext.xml:
<aop:aspectj-autoproxy/><!-- 启动使用注解配置AOP支持 --> <bean id="securityHandler" class="spring.SecurityHandler"/> <bean id="userManager" class="spring.UserManagerImpl"/>
UserManager.java
public interface UserManager {
public void addUser(String username, String password);
public void deleteUser(int id);
public void modifyUser(int id, String username,
String password);
public String findUserById(int id);
}
UserManagerImpl.java
public class UserManagerImpl implements UserManager {
public void addUser(String username, String password) {
System.out.println("----UserManagerImpl.addUser()------");
}
public void deleteUser(int id) {
System.out.println("------UserManagerImpl.deleteUser()---");
}
public String findUserById(int id) {
System.out.println("----UserManagerImpl.findUserById()--");
return null;
}
public void modifyUser(int id, String username, String password) {
System.out.println("-------UserManagerImpl.modifyUser()--");
}
}
测试端代码:
public class Client {
public static void main(String[] args) {
BeanFactory factory = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager =
(UserManager)factory.getBean("userManager");
userManager.addUser("张三", "123");
}
}
打印信息:
-------checkSecurity()---------------
-------UserManagerImpl.addUser()-----