AOP介绍
aop( aspect oriented programming ) 面向切面(方面)编程,是对所有对象或者是一类对象编程,核心是( 在不增加代码的基础上, 还增加新功能 ),也是spring的核心技术之一。
AOP术语
1.切面(aspect):要实现的交叉功能,是系统模块化的一个切面或领域。如日志记录。
2.连接点:应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出,或者要修改的
字段。
3.通知:切面的实际实现,他通知系统新的行为。如在日志通知包含了实
现日志功能的代码,如向日志文件写日志。通知在连接点插入到应用系统中。
4.切入点:定义了通知应该应用在哪些连接点,通知可以应用到AOP框架支持的任何连接点。
5.引入:为类添加新方法和属性。
6.目标对象:被通知的对象。既可以是你编写的类也可以是第三方类。
7.代理:将通知应用到目标对象后创建的对象,应用系统的其他部分不用为了支持代理对象而
改变。
8.织入:将切面应用到目标对象从而创建一个新代理对象的过程。织入发生在目标
对象生命周期的多个点上:
编译期:切面在目标对象编译时织入.这需要一个特殊的编译器.
类装载期:切面在目标对象被载入JVM时织入.这需要一个特殊的类载入器.
运行期:切面在应用系统运行时织入.
通知种类
快速入门
step
1、新建一个接口TestServiceInter
public interface TestServiceInter {
public void sayHello();
}
2、新建一个目标对象Test1Service类,并实现TestServiceInter接口
public class Test1Service implements TestServiceInter {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hi "+name);
}
}
3、前置MethodBeforeAdvice使用
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
/**
* method: 被调用方法名字
* args: 给method传递的参数
* target: 目标对象
*/
public void before(Method method, Object[] args, Object target)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("记录日志..."+"方法名称:"+method.getName()+" 目标对象:"+target);
}
}
4、配置bean
4-1、配置被代理的对象
id
="test1Service" class="com.ydc.aop.Test1Service">4-2、配置MethodBeforeAdvice通知
id="MyMethodBeforeAdvice" class="com.ydc.aop.MyMethodBeforeAdvice" />
4-3、配置代理对象
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>com.ydc.aop.TestServiceIntervalue>
list>
property>
<property name="interceptorNames">
<value>MyMethodBeforeAdvicevalue>
property>
<property name="target" ref="test1Service" />
bean>
5、运行测试
看见没,MethodBeforeAdvice的作用就是在目标对象(Test1Service)调用sayHello()方法前先调起MethodBeforeAdvice的before函数,但该函数并没有在任何地方显示调用,并且该方法可以获取到目标对象(Test1Service)的好多信息,这样一来,可在目标对象的方法调用之前可以做一些事情,比如写入日志。
6、让目标对象再实现TestServiceInter2接口
public interface TestServiceInter2 {
public void sayBye();
}
public class Test1Service implements TestServiceInter,TestServiceInter2 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hi "+name);
}
public void sayBye() {
// TODO Auto-generated method stub
System.out.println("bye "+name);
}
}
7、增加代理接口
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>com.ydc.aop.TestServiceIntervalue>
<value>com.ydc.aop.TestServiceInter2value>
list>
property>
<property name="interceptorNames">
<value>MyMethodBeforeAdvicevalue>
property>
<property name="target" ref="test1Service" />
bean>
8、测试运行
看见没,可以在多个点切入。
AOP基本原理
9、AfterReturningAdvice后置通知
9-1、新建后置通知
public class MyAfterReturningAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("执行完"+arg1.getName()+"之后关闭资源");
}
}
9-2、配置后置通知
id="MyAfterReturningAdvice" class="com.ydc.aop.MyAfterReturningAdvice" />
9-3、把后置通知织入到代理对象
<property name="interceptorNames">
<list>
<value>MyMethodBeforeAdvicevalue>
<value>MyAfterReturningAdvicevalue>
list>
property>
10、再次运行我们的程序
看见没,我们可以使用后置通知AfterReturningAdvice在目标对象执行完某一个函数之后做一下业务。
11、MethodInterceptor 通知的使用
11-1、新建MethodInterceptor通知
public class MyAroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("调用方法前:");
Object object=arg0.proceed();
System.out.println("调用方法后:");
return object;
}
}
11-2、配置MethodInterceptor通知
id="MyAroundAdvice" class="com.ydc.aop.MyAroundAdvice" />
11-3、把MethodInterceptor通知织入到代理对象
<property name="interceptorNames">
<list>
<value>MyMethodBeforeAdvicevalue>
<value>MyAfterReturningAdvicevalue>
<value>MyAroundAdvicevalue>
list>
property>
12、测试运行
看见没有,其实MethodInterceptor通知的作用=MethodBeforeAdvice作用+AfterReturningAdvice作用。
13、ThrowsAdvice 通知的使用
13-1、新建异常通知
package com.ydc.aop;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method m, Object[] os, Object target, Exception e) {
System.out.println("出大事了"+e.getMessage());
}
}
13-2、配置ThrowsAdvice通知
id="MyThrowsAdvice" class="com.ydc.aop.MyThrowsAdvice" />
13-3、把ThrowsAdvice通知织入到代理对象
<property name="interceptorNames">
<list>
<value>MyMethodBeforeAdvicevalue>
<value>MyAfterReturningAdvicevalue>
<value>MyAroundAdvicevalue>
<value>MyThrowsAdvicevalue>
list>
property>
14、测试运行
看见没,ThrowsAdvice通知主要是在抛出异常的地面切入,这样一来可以统计项目的异常崩溃信息,非常有价值。
15、bean的完整配置
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="test1Service" class="com.ydc.aop.Test1Service">
<property name="name" value="ydc" />
bean>
<bean id="MyMethodBeforeAdvice" class="com.ydc.aop.MyMethodBeforeAdvice" />
<bean id="MyAfterReturningAdvice" class="com.ydc.aop.MyAfterReturningAdvice" />
<bean id="MyAroundAdvice" class="com.ydc.aop.MyAroundAdvice" />
<bean id="MyThrowsAdvice" class="com.ydc.aop.MyThrowsAdvice" />
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>com.ydc.aop.TestServiceIntervalue>
<value>com.ydc.aop.TestServiceInter2value>
list>
property>
<property name="interceptorNames">
<list>
<value>MyMethodBeforeAdvicevalue>
<value>MyAfterReturningAdvicevalue>
<value>MyAroundAdvicevalue>
<value>MyThrowsAdvicevalue>
list>
property>
<property name="target" ref="test1Service" />
bean>
beans>