AOP(Aspect Oriented Programming):剖解开封装的对象内部,并将那些影响了多个类的公共封装到一个可重用模块,并将其命名为"Aspect",即切面,通过动态代理
实现。
AOP把软件系统分为2部分,核心切入的,
AOP目前只支持对方法
的连接点,可以类比,事件处理模型。
通知类型,可以通过try-catch-finilly
来记忆。
配置:1.引入aop命名空间和xsi(变量类型定义)
<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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--特别关键,要想生效-->
<aop:aspectj-autoproxy/>
</beans>
- 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点,这些方法包括,需要日志输出,或者安全处理、或者异常处理的方法。
- 切面:切面就是对拦截处理的类,是横向关注点的抽象。
- 连接点:a join point always represents a method execution.
- 通知(advice):指拦截到连接点之后要执行的代码
- 目标对象:被通知的切面类. An object being advised by one or more aspects.
- AOP proxy:In the Spring Framework,
an AOP proxy is a JDK dynamic proxy or a CGLIB proxy
. - Weaving:将切面应用到目标对象并导致代理对象创建的过程.
AOP用途:日志、安全、异常处理。
AOP实现方式:
- 动态代理[内置aop实现]。
- 使用==框架aspectj==来实现,因为spring aop只支持`方法`,Not 属性。
We believe that both proxy-based frameworks such as Spring AOP and full-blown frameworks such as AspectJ are valuable and that they are complementary, rather than in competition
基于注解的启用方法,需要再xml
配置文件中启动AOP
<aop:aspectj-autoproxy/>
使用方法,声明类为切面类@Aspect
,然后设置监听方法。
前提:都要能够被IoC容器管理。
@Aspect//表示一个切面类
@Component//被IoC扫描
public class AopTry {
@Before(value = "execution(public void ioc_bean01.OrderServer.before())")
public void beforeLog(JoinPoint joinPoint){
System.out.println("before ,in AopTry");
Signature signature=joinPoint.getSignature();
String name=signature.getName();
Object[] args=joinPoint.getArgs();
System.out.println("SmartAspect2 前置通知 " + " 目标方法的名称是 " + name + " 参数 " + Arrays.asList(args));
}
}
切入点表达式:通过表达式定位一个或多个具体的连接点。对哪些方法进行拦截。
execution([权限修饰符][返回值类型][全类名].[方法名][参数列表])
<aop:pointcut expression="execution(* save*(..))" id="pt"/>
<!--第一个*任意修饰符和返回值类型-->
拦截所有save开头的方法
..任意匹配的参数类型和数量
环绕通知可以完成其它四个通知要做的事情:内容:try-catch-finilly
获取返回值
@AfterReturning(value = "execution(public int ioc_bean01.OrderServer.sayHello())",returning = "ret")
public void after(JoinPoint joinPoint,Object ret){
Signature signature=joinPoint.getSignature();
System.out.println(signature.getName());
System.out.println("执行后,返回值为"+ret);
}
切入表达式重用
,@Pointcut当同一个函数,有多个切面在同一点切入,@Order(value="1")作用于类
。
基于xml
的AOP,此时需要定义一个切入类。
<context:component-scan base-package="ioc_bean01"/>
<!-- <aop:aspectj-autoproxy/>-->
<!-- 切面类定义-->
<bean id="aoptry" class="ioc_bean01.AopTry"/>
<aop:config>
<aop:pointcut id="myCutPoint" expression="execution(public void ioc_bean01.OrderServer.*(..))"/>
<!-- 切面类,传说中的切面类,返回值与throwing不能需要和切面中的类保持一致。-->
<aop:aspect ref="aoptry" order="1">
<aop:after method="beforeLog" pointcut-ref="myCutPoint"/>
<aop:before method="beforeLog" pointcut-ref="myCutPoint"/>
</aop:aspect>
</aop:config>