入门案例
// 接口及其实现类
public interface AccountService {
void transform();
}
public class AccountServiceImpl implements AccountService {
@Override
public void transform() {
System.out.println("这是业务代码");
}
}
// 该类就是模仿的日志类
package com.log;
public class Logger {
public void beforeLog(){
System.out.println("前置通知");
}
public void returningLog(){
System.out.println("后置通知");
}
public void throwingLog(){
System.out.println("异常通知");
}
public void afterLog(){
System.out.println("最终通知");
}
}
// 基于接口的动态代理,实现对 accountService 方法的增强
import com.log.Logger;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInstance {
private static final Logger logger = new Logger();
public static Object getInstance(final Object obj){
return Proxy.newProxyInstance(ProxyInstance.class.getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
// 前置通知
logger.beforeLog();
// 方法执行
result = method.invoke(obj);
// 后置通知
logger.afterLog();
} catch (Exception e) {
// 异常通知
logger.throwingLog();
} finally {
// 最终通知
logger.afterLog();
}
return result;
}
});
}
}
// 测试类
public class ApplicationTest {
public static void main(String[] args) {
// 测试动态代理
AccountService accountService = new AccountServiceImpl();
AccountService instance = (AccountService) ProxyInstance.getInstance(accountService);
instance.transform();
}
}
AOP 术语
AOP
中的术语相对其他来说还是挺多的,我会结合上面的案例对相关的属于进行一个介绍
连接点(Joinpoint
)
概念:连接点是指那些被拦截到的点,就是 Spring
允许使用通知的地方
示例:在方法执行的地方 (method.invoke(obj)
) 的前面、后面、抛出异常的地方都是连接点
注意点:这些点上只能使用方法,SPring
值支持方法类型的连接点
切入点(Pointcut
)
概念:所谓的切入点是指我们要对哪些 Joinpoint
进行拦截的定义
示例:若只是在 method.invoke(obj)
前进行拦截,就是只在方法执行前使用了通知,那么方法前就是切入点;
通知(Advice
)
概念:所通知是指拦截到 Joinpoint
之后所要做的事情就是通知
示例:该案例中在方法前使用了 logger.beforeLog()
,该方法就是做的事情就是前置通知
通知类型:前置通知,后置通知,异常通知,最终通知,环绕通知
切面(Aspect
)
概念:切入点和通知的结合;通知说明了要干什么,而切入点则说明了在什么地方干,当两个相结合就是一个切面的完整定义
引入(Introduction)
概念:引介是一种特殊的通知,在运行期中可以在不修改类代码的前提下为类动态地添加一些方法或 Field
目标对象(Target)
概念:代理的目标对象
示例:相当于案例中的 AccounService
对象,虽然获得的实例是代理对象,但是执行的方法确实目标对象的
织入(Weaving)
概念:把切面应用到目标对象来创建新的代理对象的过程
示例:案例中使用动态代理技术,对 transform
方法进行增强时,将 Logger
的方法加入其中
注意点:Spring
采用动态代理织入,而 AspectJ
采用编译期织入和类装载期织入。
代理(Proxy
)
概念:一个类 AOP
织入增强后,就产生一个结果代理类