聊聊Spring框架AOP

AOP是什么?
aop有个拉风的名字《面向切面编程》,是OOP的补充。好听的说aop就是将一批具备逻辑相关性的类视作一个切面,并以切面为单位,添加功能;通常用于实现具备横切性质的系统级服务。通俗的说aop就是在极少影响原程序的代码的前提下,在程序中的某些地方(即不在原程序中添加其他代码)为原程序切入一些额外的功能。

AOP名词解释
连接点 JoinPoint : ,连接点就是被拦截到的程序执行点,因为Spring只支持方法类型的连接点,所以在Spring中连接点就是被拦截到的方法。
通知 Advice : 需要向切面加入的功能。
实现: 前:before
后:after
环绕:around
异常:after-throwing
返回:after-returning
引入 Introduction: 对目标对象添加方法和属性
切面 Aspect : 将切面模块化,包含了要切入的功能,切入点等等,可以简单地认为, 使用 @Aspect 注解的类就是切面。
目标对象 Target: 目标对象指将要被增强的对象,即包含主业务逻辑的类对象。或者说是被一个或者多个切面所通知的对象。
代理 Proxy : AOP的一种实现方式。
织入 Weaving: 将切面应用到目标对象的过程。
切入点 PointCut : 所有的方法都可以认为是连接点,但是我们并不希望在所有的方法上都添加通知,而切入点的作用就是提供一组规则(使用 AspectJ pointcut expression language 来描述) 来匹配连接点,给满足规则的连接点添加通知。

实现原理
aop的实现----代理Proxy
aop的实现代码:

创建一个接口
public interface KillPigService {
double kill(String pigName);
}

被代理的类,实现KillPigService 的Kill方法。
public class KillPigServiceImpl implements KillPigService {
@Override
public double kill(String pigName) {
    System.out.println("屠宰:"+pigName);
    return 100;
}
}

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

代理类,实现KillPigService 的Kill方法。
public class KillPigServiceImplProxy implements KillPigService {
private KillPigServiceImpl killPigServiceImpl = new KillPigServiceImpl();
@Override
public double kill(String pigName) {
    long before = System.currentTimeMillis();
    double result =  killPigServiceImpl.kill(pigName);
    long after = System.currentTimeMillis();
    System.out.println("执行 killPigServiceImpl#kill方法结束,耗时"+(after-before)+"毫秒");
    return result;
}

}

如果接口加一个方法,所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。

动态代理:在程序运行时,运用反射机制动态创建而成。

public class DynamicProxy implements InvocationHandler {
	//通过InvocationHandler 实现方法拦截加入代理功能
private Object target;

public Object getProxy(Object target){
    this.target=target;
    //this指的是当前实例,当前实例持有了被代理的实例
    return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    //通过Proxy类创建动态代理实例
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	//Object proxy:指被代理的对象。 Method method:要调用的方法 Object[] args:方法调用时所需要的参数 
    System.out.println(method.getName() + "执行,参数为"+ Arrays.toString(args));
    long before = System.currentTimeMillis();
    Object result = method.invoke(target, args);
    long after = System.currentTimeMillis();
    System.out.println(method.getName() + "执行,耗时"+(after-before)+"毫秒");

    return result;
}
}

当调用生成的代理实例时,会被invocationHandler的方法拦截,方法实现就是代理的内容。

应用场景
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值