AOP概念
AOP aspect Oriented Program 面向切面(方面)编程
采取横向抽取机制,取代传统的纵向继承体系重复性代码,一般实现:性能监控,事务管理,安全检查,缓存等功能
原理
对于扩展功能来说
原来:修改源代码
后来:纵向抽取机制,继承BaseClass,调用super方法()
再后来:横向抽取机制
底层:动态代理方式实现 :
使用动态代理创建接口的*实现类的代理对象*(一个对象能实现和原来的对象相同的功能,和原来的对象平级,也实现了接口,但不是真正的对象)
针对有接口的对象:jdk的动态代理
针对任意对象:cjlib动态代理:创建其子类的动态代理对象,子类中调用父类的方法增强
(代理有三种方式静态,jdk动态,cjlib动态)
操作术语
Joinpoint:连接点:可以被增强的方法(Spring只支持方法类型的连接点)
Pointcut:切入点:实际增强的方法
Advice:通知/增强:实际增强方法的逻辑(就是一个方法)
前置通知:
后置通知:
异常通知:出现异常时出现的通知
最终通知:在后置之后来执行的通知
环绕通知:之前之后都可以通知
Aspect:切面:把通知应用在具体的方法上面的过程,称为切面(把增强应用到切入点上的过程)
Introduction:引介:可以动态向类中增加属性和方法
Target:目标对象:增强方法所属的对象
Weaving:织入:把增强用到目标的过程
Proxy:代理:一个类被AOP增强之后就产生一个结果代理类
配置使用
1.使用表达式配置切入点
常用表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
(1)execution(* com.luhao.service.IBookService.add(..))方法要写全路径
(2)execution(* com.luhao.service.IBookService.*(..))
(3)execution(* *.*(..)) 任意类任意方法都增强
(4)save*.*(..)
(5)com.luhao.service.*(..) 不包含子包
(6) com.luhao.*..*(..) 包含子孙包
...
2.使用AspectJ实现AOP
AspectJ是一个面向切面的单独的框架,拓展了Java语言.可以配合Spring一起来实现AOP
Spring2.0以后增加了AspectJ的支持
有两种方式:
1.基于Aspectj的xml配置文件
2.基于Aspectj的注解的方式
流程:
1.Jar包(aop,aspect,两个依赖)
2.约束(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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
</beans>
3.创建类,配置对象
4.在aop-config中配置切入点
<aop:pointcut expression="execution(public *.*(..))" id="pointcut1">
切面aop:aspect
<aop:aspect ref="增强的类">
<aop:before method="增强的类中的方法作为前置增强" pointcut-ref="pointcut1">
</aop:aspect>
aop:after-returning :后置
aop:after:最终
aop:around:环绕需要参数:proceedingJoinPoint
<?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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描需要的包 -->
<context:component-scan base-package="com.luhao.*"></context:component-scan>
<!-- 创建需要的对象-->
<bean id="userAspect" class="com.luhao.aop.UserAspect"></bean>
<bean id="userService" class="com.luhao.service.impl.UserServiceImpl"></bean>
<bean id="userDao" class="com.luhao.dao.impl.UserDaoImpl"></bean>
<!-- 配置切点 -->
<aop:config>
<aop:pointcut expression="execution(* com.luhao.*..*(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="userAspect">
<!-- <aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="after" pointcut-ref="pointcut1"/> -->
<aop:around method="around" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>