Spring框架
面向切面编程:
面向切面编程[Aspect Oriented Programming,简称AOP]指在运行时,动态的将代码切入到类的指定方法或位置上的编程思想.
术语:
aspect(切面): 指横切性关注点的抽象即为切面,它与类相似,类是对物体特征的抽象.[通俗讲,切面是定义了额外功能的类]
joinpoint(连接点): 指被拦截的点,分为属性,方法,构造器.Spring只支持方法类型的连接点.[通俗讲,应用额外功能的地方称为连接点]
pointcut(切入点): 指对"连接点"进行拦截的定义.[通俗讲,控制"哪些地方"应用切面]
advice(通知): 指拦截到"连接点"之后所要做的事情.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知.
target(目标对象): 指要使用切面的类.
weave(织入): 指将"切面"应用到"目标对象"并导致"代理对象"创建的过程称为织入.
introduction(引入): 在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field.
通知类型:
前置通知: 在目标方法执行之前,执行前置通知
后置通知: 在目标方法执行之后,执行后置通知
异常通知: 在目标方法执行并抛出异常时,执行异常通知
最终通知: 在目标方法执行之后或抛出异常时,执行最终通知
环绕通知: 在前置通知和目标方法之前,以及最终通知之前执行环绕通知
Spring提供了多种方式实现AOP,常用:JDK动态代理和CGLIB代理
JDK动态代理:
使用Proxy类创建代理对象,含有处理类必须实现InvocationHandler接口.目标类必须实现接口[不限制类型],JDK动态代理通过实现目标类实现的所有接口,实现动态代理功能
CGLIB代理:
使用Enhancer类生成代理对象,含有处理类必须实现MethodInterceptor接口.CGLIB通过生成目标类的子类,并重写目标类非final的方法实现动态代理功能
代理方式选择:
1.默认情况下,目标对象[被拦截的对象]必须实现了接口,Spring才会使用JDK动态代理.否则,Spring自动使用CGLIB代理
2.当目标对象实现了接口,可以设置aop:aspectj-autoproxy的proxy-target-class为true,强制使用CGLIB代理
开发步骤:
第1步: 添加jar包
Spring基本jar+AOP相关jar
第2步:编写切面类,设置切入点和通知
@Aspect: 编写在类声明上面,表示声明当前类为切面类
@Pointcut: 编写在方法上面,定义切入点要求,"方法名()"即为切入点名
@Before: 编写在方法上面,表示声明当前方法为前置通知
格式: @Before(value=“切入点名”,argNames=“参名,…”)
@AfterReturning: 编写在方法上面,表示声明当前方法为后置通知
格式: @AfterReturning(value=“切入点名”,return=“参数名[接收返回值]”)
@After: 编写在方法上面,表示声明当前方法为最终通知
格式: @After(value=“切入点名”)
@AfterThrowing: 编写在方法上面,表示声明当前方法为例外通知
格式: @AfterThrowing(value=“切入点名”,throwing=“参数名[接收异常对象]”)
@Around: 编写在方法上面,表示声明当前方法为环绕通知
格式: @Around(value=“切入点名”)
说明:
public Object 环绕通知(ProceedingJoinPoint point){
Object rs=point.proceed();//继续执行下1个通知或调用目标方法
return rs; //必须返回,否则后置通知无法获得目标方法返回值
}
注意: @Before,@AfterReturning,@After,@AfterThrowing,@Aroud默认属性为value[切入点名]
表达式:
execution(返回值类型 目录.类名.方法名(参数类型,..) && args(参数名,参数名,..))
说明:
1.返回值类型为void或类型全名,可配合"!“使用.[!void表示有返回值]
2.任意返回值/任意类名/任意方法名,都可以用”*“表示.
3.若包含指定目录的任意子目录,用”.“表示
4.参数类型为类全名.任意个数和类型用”…"表示.
5.args()表示必须有指定个数的参数
execution(* service.UserService.*(…))
第3步: 开启aspectj自动代理,并注册切面类
<aop:aspectj-autoproxy/><!--启动AspectJ自动代理功能-->
第4步: 注册AOP
<!--注册切面类-->
<bean id="myaop" class="aop.MyAOP" />
或
@Component
第5步: 正常编写程序,测试AOP效果
过滤器: 过滤所有请求 web.xml\url-pattern设置过滤目标
AOP: 拦截方法 在切面类中切入点上说明拦截目标
思路:
第1步: 拦截资源
第2步: 操作
第3步: 释放资源
XML方式实现AOP
步骤:
第1步: 添加jar包
同annotation方式
第2步: 编写切面类
同annotation方式,但是移除所有的注解[在配置文件中实现注解的功能].
第3步: 编写Spring配置文件
a.将切面类交给Spring管理
b.配置面向切面
<aop:config>
<!--定义1个切面类-->
<aop:aspect id="myaop" ref="myAOP">
<!--定义1个切入点-->
<aop:pointcut id="mycut" expression="execution(* service.UserService.*(..))"/>
<!--定义通知-->
<aop:before method="beforeDeal" pointcut-ref="mycut" arg-names="joinPoint" />
<aop:after-returning method="afterReturningDeal" pointcut-ref="mycut" returning="returnData"/>
<aop:after method="afterDeal" pointcut-ref="mycut" />
<aop:after-throwing method="afterThrowingDeal" pointcut-ref="mycut" throwing="e"/>
<aop:around method="aroundDeal" pointcut-ref="mycut" />
</aop:aspect>
</aop:config>
第4步: 编写程序,测试
同annotation方式