spring之AOP

1、什么是AOP?没有AOP会怎么样

在前面我们提了IOC,作为spring的两大核心功能,AOP(Aspect-OrientedProgramming,面向方面编程)也是非常重要的,它体现了一种相对于OOP(Object-Oriented Programing,面向对象编程),而进一步完善了补充。在之前我们提到过,IOC是整个spring的核心功能,它管理着Bean,解耦了各个类。而AOP呢则是分散的类将其类似的部分抽取出来。如果说OOP解决的是一种上下级关系,则AOP则解决的是一种左右级关系。因为OOP定义的是一种上下级属性,所以当我们遇到分散的对象之间有公共行为的时候,OOP显得比较无力(只是无力,而不是实现不了)。比如日志管理,所以就要用AOP来解决了。

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

另外AOP的实现依赖于BeanPostProcessor(后置处理器),如果了解过IOC的应该知道BeanPostProcessor是在IOC实例化bean之前的一个行为。所以可以说AOP是IOC的一种拓展。使Bean在初始化的时候做一些其他的事情

aop使用的场景:
Authentication 权限

Caching 缓存

Context passing 内容传递

Error handling 错误处理

Lazy loading 懒加载

Debugging  调试

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Performance optimization 性能优化

Persistence  持久化

Resource pooling 资源池

Synchronization 同步

Transactions 事务

2、如何实现

大致可以分为以下流程(我们前面提到过AOP是IOC的一个拓展,所以我们可以回头看一下IOC的refresh里面是怎么实现这个拓展的):
1、创建IOC容器
2、注册配置类调用refresh
3、刷新registerBeanPostProcessor
4、注册bean的后置处理器(beanPostProcessor)来拦截bean的创建,
5、利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;(拦截器链就是一个个的增强器组成)
(其中的细节依赖于动态代理,Spring默认使用的是JDK代理)
看一看这个流程前面是不是跟IOC的初始化有点类似。所以我们可以看到AOP其实是加在IOC里面的,通过源码我们也可以看一下

	@Override
	    @Override
    public void refresh() throws BeansException, IllegalStateException {
       // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
       synchronized (this.startupShutdownMonitor) {
     
          // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
          prepareRefresh();
     
          // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
          // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
          // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
     
          // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
          // 这块待会会展开说
          prepareBeanFactory(beanFactory);
     
          try {
             // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
             // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
     
             // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
             // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
             postProcessBeanFactory(beanFactory);
             // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
             invokeBeanFactoryPostProcessors(beanFactory);
     
             // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
             // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
             // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化



			/*
			*看这里,这个方法其实就是在创建IOC容器中执行的。
			*/
             registerBeanPostProcessors(beanFactory);//()




     
             // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
             initMessageSource();
     
             // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
             initApplicationEventMulticaster();
     
             // 从方法名就可以知道,典型的模板方法(钩子方法),
             // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
             onRefresh();
     
             // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
             registerListeners();
     
             // 重点,重点,重点
             // 初始化所有的 singleton beans
             //(lazy-init 的除外)
             finishBeanFactoryInitialization(beanFactory);
     
             // 最后,广播事件,ApplicationContext 初始化完成
             finishRefresh();
          }
     
          catch (BeansException ex) {
             if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                      "cancelling refresh attempt: " + ex);
             }
     
             // Destroy already created singletons to avoid dangling resources.
             // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
             destroyBeans();
     
             // Reset 'active' flag.
             cancelRefresh(ex);
     
             // 把异常往外抛
             throw ex;
          }
     
          finally {
             // Reset common introspection caches in Spring's core, since we
             // might not ever need metadata for singleton beans anymore...
             resetCommonCaches();
          }
       }
    }

其他具体内容参考:
https://www.cnblogs.com/oumyye/p/4467276.html java框架篇—spring AOP 实现原理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值