Spring AOP 原理
原理:一种编程技术,用来在系统中提升业务分离
AOP术语
1、Aspect切面
实现的交叉功能
2、JoinPoint 连接点
应用程序执行过程中插入切面的地点
3、Advice 通知
通知某个切入点执行的代码
4、Point cut 切入点
定义了通知应该用在哪些的连接点
5、Instroduction 引入
允许已存在类添加的新方法和属性
6、Target 目标对象
被通知的对象
7、Proxy 代理
AOP框架创建对象,用来实现切面契约,包括通知方法执行等功能,将通知应用到目标对象后创建的对象
8、 Weaving 织入
将切面应用到目标对象从而创建一个新的代理对象过程
相关驱动包
aspectjweaver.jar
aspectjrt.jar
创建通知
1、Before 前置通知
public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("执行了:"+arg0.getClass().toString()+"目标类");
System.out.println("执行了:"+arg2.getClass().getName()+"该类");
System.out.println("执行了:"+arg0.getName()+"()方法");
for(Object object : arg1){
System.out.println("参数为:"+object);
}
System.out.println("前置通知");
}
备注:实现的接口为
import org.springframework.aop.MethodBeforeAdvice;
2、After 后置通知
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
System.out.println("执行了:"+arg1.getClass().toString()+"类");
System.out.println("执行了"+arg1.getName()+"()方法");
for(Object object : arg2){
System.out.println("参数为:"+object);
}
System.out.println("后置通知");
}
备注:实现的接口
import org.springframework.aop.AfterReturningAdvice;
3、Round 环绕通知
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("前置通知2222222222");
System.out.println("执行了:"+arg0.getThis().getClass()+"类");
System.out.println("执行了:"+arg0.getMethod().getName()+"()方法");
Object [] object =arg0.getArguments();
for(Object ob: object){
System.out.println("参数为:"+ob+"");
}
Object obj = arg0.proceed();
System.out.println("后置通知2222222222");
return obj;
}
备注:要实现的接口
import org.aopalliance.intercept.MethodInterceptor;
4、异常通知
public void afterThrowing(Throwable t){
System.out.println("抛出了"+t.getMessage()+"异常");
}
备注:实现的接口
import org.springframework.aop.ThrowsAdvice;
配置 ApplicationContext.xml
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
>
<!--人 (目标对象) -->
<bean id="shopingMan" class="com.lovo.spring1.PeopleImp"></bean>
<!-- 购物(通知对象) -->
<bean id="myadvice" class="com.lovo.spring1.SpringProxyAOP"></bean>
<!-- 工具(切面) -->
<bean id="myInterceptor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 在该切面上加入哪个通知 -->
<property name="advice" ref="myadvice"></property>
<!-- 哪些类需要进行注入通知 -->
<property name="patterns" value="com.lovo.spring1.*.*"></property>
</bean>
<!-- 定义代理 -->
<bean id="proxy" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean" >
<!-- 定义当前目标对象,需要使用哪些切面 -->
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
<!-- 物品(指明具体做哪个类的代理) -->
<bean id="info" parent="proxy">
<property name="target" ref="shopingMan"></property>
</bean>
</beans>