文章目录
前言
好记性不如烂笔头,做记录亦是复习。加油
一、AOP介绍
AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往是权限校验代码、日志代码、事务控制代码、性能监控代码。
上图描述的就是未采用AOP思想设计的程序,当红色框中圈定的方法时,会带来大量的重复劳动。
程序中充斥着大量的重复代码,使程序的独立性很差。而下图中是采用了AOP思想设计的程序,它把红框部分的代码抽取出来的同时,运用动态代理技术,在运行期对需要使用的业务逻辑方法进行增强。
Spring 实现AOP思想使用的是动态代理技术,默认情况下Spring会根据被代理对象是否实现接口来选择使用JDK还是CGLIB。当被代理对象没有实现任何接口时,Spring会选择CGLIB。当被代理对象实现了接口,Spring会选择JDK官方的代理技术,不过可以通过配置的方式,让Spring强制使用CGLIB。
二、AOP源码剖析
好处: 提高培养代码架构思维、深入理解框架
原则:
定焦原则:抓主线
宏观原则:站在上帝视角,关注源码结构和业务流程(淡化具体某行代码的编写细节)读源码的方法和技巧
断点(观察调用栈)
反调(Find Usages)
经验(spring框架中doXXX,做具体处理的地方)
Spring源码构建步骤:
1.从github下载源码
2.安装gradle 5.6.3(类似于maven) Idea 2019.1 Jdk 11.0.5
3.导入(耗费⼀定时间)
4.编译工程(顺序:core-oxm-context-beans-aspects-aop)工程—>Tasks—>other—>compileTestJava
1.代理对象创建
1.1 AOP基础用例准备
Bean定义
@Component
public class LagouBean {
public void tech() {
System.out.println("java learning......");
}
}
Aspect定义
@Component
@Aspect
public class LagouAspect {
@Pointcut("execution(* com.lagou.*.*(..))")
public void pointcut() {
}
@Before("pointcut()")
public void before() {
System.out.println("before method ......");
}
}
测试用例
/**
* 测试⽤例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild() {
ApplicationContext applicationContext = new
AnnotationConfigApplicationContext(SpringConfig.class);
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
lagouBean.tech();
}
1.2 时机点分析
可以在 getBean 之前,LagouBean对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib代理对象),所以可以断定,容器初始化过程中目标Bean已经完成了代理,返回了代理对象。
1.3 代理对象创建流程
AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object,
org.springframework.beans.factory.support.RootBeanDefinition)
/**
* 初始化Bean
* 包括Bean后置处理器初始化
* Bean的⼀些初始化⽅法的执⾏init-method
* Bean的实现的声明周期相关接⼝的属性注⼊
*/
protected Object initializeBean(final String beanName, final Object bean,
@Nullable RootBeanDefinition mbd) {
// 执⾏所有的AwareMethods
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器⽅法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean,
beanName);
}
try {
// 这⾥就开始执⾏afterPropertiesSet(实现了InitializingBean接⼝)⽅法和initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 整个Bean初始化完成,执⾏后置处理器⽅法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 循环执⾏后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
*
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String
beanName) {
if (bean != null) {
// 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B。
// 当真正需要创建B时,就没必要再代理⼀次已经代理过的对象),避免重复创建
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}