上篇博客中我们介绍了Spring中的IoC控制反转,本篇博客介绍我们介绍Spring中的另一个核心AOP切面编程。
AOP是Spring中对OOP的补充,由面向对象编程转到了面向切面编程,针对业务处理过程中的切面进行提取,然后降低各部分之间的耦合。通过下面的图我们来了解AOP中的几个基本概念,从而更深一步的认识AOP:
Cross cutting concern:横切性关注点,是一种独立的服务,它会遍布在系统的处理流程之中。
Aspect:表示切面,是对横切性关注点的模块化。切面采用Spring的Advisor或拦截器实现。
Joinpoint:表示连接点,Advice在应用程序中执行的点,Spring只支持方法的joinpoint,这个点也可以使属性修改。
Advice:表示通知,是对横切性关注点的具体实现。
Pointcut:表示切入点,它定义了Advice应用到哪些Joinpoint上,对Spring来说就是方法调用。开发者必须指定一个切入点
Target Object:表示目标对象,也即Advice被应用的对象。
AOP Proxy:AOP代理,在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
Weaving:表示织入,将Advice应用到TargetObject上的过程叫做织入,Spring支持动态织入。
下面我们采用Annotation方式讲解Spring对AOP的支持:
1、添加Spring的依赖包配置:
*SPRING_HOME/dist/spring.jar
*SPRING_HOME/lib/log4j/log4j-1.2.14.jar
*SPRING_HOME/lib/jakarta-commons/commons-logging.jar
* SPRING_HOME/lib/aspectj/*.jar
2、建立SecurityHandler.java类,将横切性关注点模块化,采用注解指定SecurityHandler为Aspect,定义Advice和Pointcut
package com.bjpowernode.spring;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class SecurityHandler {
/**
* 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数
* 该方法就是一个标识,不进行调用
*/
@Pointcut("execution(* add*(..))")
private void addAddMethod(){};
/**
* 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
@Before("addAddMethod()")
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}
3、在配置文件中启用AspectJ对Annotation的支持:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 启用AspectJ对Annotation的支持 -->
<aop:aspectj-autoproxy/>
<bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
</beans>
application-config.xml中,只需要配置业务逻辑bean和Aspect bean,并启用Aspect注解即可。
4、下面采用配置方式讲解Spring对AOP的支持。
其他方式与上面的方式一样,最重要的就是配置文件的不同:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
<!-- 采用配置文件 进行配置 -->
<aop:config>
<aop:aspect id="securityAspect" ref="securityHandler">
<!-- 包下的所有类的添加和删除方法起作用 -->
<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) ||execution(* com.bjpowernode.spring.*.del*(..))"/>
<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
</aop:aspect>
</aop:config>
</beans>
在配置文件中重要的就是expression的匹配路径:
<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>表示对所有以add开头的方法起作用。
<aop:pointcut id="addAddMethod" expression="execution(*com.bjpowernode.spring.*.*(..))"/>表示在com.bjpowernode.spring包下所有的方法都会起作用。
在AOP中,最重要的就是发现切面,然后在运行时讲切面织入进去,在这个过程中默认采用动态代理,使得方法的复用性大大提高,提高了系统的可靠性。