A.背景知识:
aop 是spring 中面向切面编程的实现。
面向切面编程,理解为将系统中多出公共操作代码抽象出来的模块;在运行时动态地将代码切入到指定的类的指定方法的指定位置的编程是想叫做面向切面编程;
B.基本概念:
切面(aspect):从对象中抽象出来的横切性功能模块,由通知和切入点组成叫做切面;例如,日志操作、权限控制;
通知(advice):切面的具体实现,例如日志操作的代码。定义为切面的某个方法;
连接点(JoinPoint):目标对象中插入通知的地方,即advice 的应用位置;
切入点(pointcut):切面的一部分对应为表达式,定义了通知作用于什么样的连接点上,即advice 的应用范围;
目标对象(target):那些即将切入切面的对象。这些对象中只剩下干干净净的业务代码;
代理对象(proxy):将通知应用到目标对象之后所创建的代理对象;
织入(weaving):将切面应用于目标对象到创建出代理对象的过程;
这是spring-aop实现的两个实例:
1.通过注解的方式实现aop:
1.1配置文件:
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 使用annotation自动注入bean,并启动相关处理注解的进程 -->
<context:component-scan base-package="phda.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>
其中:proxy-target-class取值true|false 采用jdk动态代理||采用cglib动态代理。
1.2切面
package phda.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
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;
/**
* 自定义一个aop 切面
* @author Administrator
*/
@Aspect
@Component
public class TestAop implements ITestAop{
public TestAop(){
System.out.println("init testAop");
}
@Pointcut("execution(* phda.server.StudentServer.*(..))")
public void tt(){
System.out.println("cut point");
}
@Before("tt()")
public void beforeFn(JoinPoint join){
Object[] objArr = join.getArgs();
for(Object obj : objArr)
System.out.println(obj.toString());
System.out.println("切入点:"+join+" ");
//System.out.println(fileName);
System.out.println("before");
}
@After("tt()")
public void afterFn(JoinPoint join){
System.out.println("after");
}
@Around("tt()")
public void aroundAdvice(ProceedingJoinPoint dd ) throws Throwable{
System.out.println("around...");
dd.proceed();
System.out.println("around...after");
}
@AfterReturning("tt()")
public void afterAdvice(){
System.out.println("return ....");
}
@AfterThrowing("tt()")
public void afterThrow(JoinPoint joinPoint, Exception e){
System.out.println("throw after"+e.getMessage());
}
}
2.通过配置文件的方式实现aop
2.1配置文件内容:
<bean id="testAop2" class="phda.aop.TestAop2"></bean>
<!-- 通过配置的方式实现aop 功能 -->
<aop:config>
<aop:aspect id="aop2" ref="testAop2">
<aop:pointcut expression="execution(* phda.server.StudentServer.*(..))" id="pointcut2"/>
<aop:before method="beforeAdvice" pointcut-ref="pointcut2"/>
</aop:aspect>
</aop:config>
2.2切面代码:
public class TestAop2 {
public void beforeAdvice(JoinPoint join){
System.out.println("before.. by config file");
}
}
上面这些知识部分代码:
实例项目下载: