AOP
一.概念:
- 面向切编程:使用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个之间的耦合度降低,提高程序的可重用性,提高了开发效率。
- 不通过修改代码方式,添加新的功能(新功能单独写一个模块,通过方式加入其中,不改变原来的模块代码)
二.底层原理:
1.Aop底层使用动态代理
有两种情况:
- 有接口情况,使用JDK代理
创建接口实现类代理对象,增强类的方法 - 没有接口情况,使用CGLIB动态代理
创建子类的代理对象,增强类的方法
2.JDK动态代理过程
使用Proxy类里面的方法创建代理对象
-
调用newProxyInstance方阿飞,三个参数:(类加载器,增强方法所在类,这个类实现的接口支持多个接口,实现nvocationHandler创建代理对象,写增强的方法)
-
编写JDK动态代理代码
1.创建接口,定义方法
2.创建接口实现类,实现方法
3.使用Proxy类创建接口代理对象
3.Aop操作,准备工作
1.spring框架基于AspectJ实现Aop操作
2 基于AspectJ实现Aop操作
1)基于xml配置文件实现
2)基于注解方式实现(较多使用)
3 .切入点表达式
作用:知道对哪一个类里面的哪个方法进行增强
语法结构:(权限修饰符:private\public\static等 *表示任意的修饰符)
execution([权限修饰符][返回类型][类全路径][方法名称][参数列表])
例:对com.spring.UserDao类里面的add进行增强
execution(*com.spring.UserDao.add(参数))
例:对com.spring.UserDao类里面的所有方法进行增强
execution(*com.spring.UserDao.*(参数))
例:对com.spring.包里面的所有类,类里面的所有方法进行增强
execution(*com.spring.*.*(参数))
4 .AOP操作,AspectJ注解实现
-
创建类,在类里面定义方法
-
创建类,在类里面写增强的逻辑
在增强类里面,创建方法,让不同的方法代表不同的通知 -
进行通知的配置
1)在Spring的配置文件中,开启注解扫描(需要使用context名称空间)
<context:component-scan base-package=“com.spring.aop”/>
2)使用注解创建User和UserProxy对象
@Component
3)在增强类上边添加注解@Aspect ,生成代理对象
@Aspect
4)在spring配置文件中开启代理对象(需要使用aop名称空间)
<aop:aspect-autoproxy/>
5)配置不同类型的通知(前置、后置、环绕、异常、最终)
在增强类的里面,在作为通知的方法上边添加通知类型注解,使用切入点表达式配置
@Before(value=“execution(* com.spring.aop.User.add())”)
after是在方法之后执行,发生异常也会执行
afterReturning是在返回值之后执行,发生异常之后不会再执行
afterThrowing是只有发生了异常才会执行,没发生异常就不执行
@Around(环绕通知):需要在中间执行被增强的方法,利用ProceedingJoinPoint proceedingJoinPoint 的proceed(),执行被增强的方法执行。
6 ) 相同的切入点进行抽取
@Pointcut(value=“execution(* com.spring.aop.User.add())”)
public void pointdemo(){}
7 ) 有多个增强类对同一个方法进行增强,设置增强类优先级
·在增强类上面添加注解@Order(数字类型值),数字类型值越小,优先级越高
-
AOP操作,AspectJ xml配置文件实现
1)创建两个类,增强类和被增强类,创建方法
2)在Spring配置文件中创建两个类对象
<bean id="" class="">
<bean id="" class="">
3)在Spring配置文件中配置增强(使用aop名称空间)
<aop:config>
1.配置切入点
<aop:pointcut id=“随意命名” expression=“切点表达式”>
2.配置切面(切面:把通知应用到切入点的过程)
<aop:aspect ref=“增强类” >
3.增强作用在具体的方法上
<aop:before method=“增强方法名” pointcut-ref=“配置切入点时的id”/>
<aop:aspect/>
<aop:config/>
-
AOP操作,完全使用注解开发
·创建配置类,不需要创建xml配置文件
@Configuration
@ComponentScan(basePackages={’’})
@EnableAspectJAutoProxy(proxyTargetClass = true)