1、切面实现的两种方式
1、@Aspect注解模式
2、通过xml配置
1、入口spring.factories文件中的org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
先解释两个
a、@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,AnnotatedElement.class })
判断当前classpath下是否存在指定类,若存在则将当前的配置装载入spring容器,需要引入spring-context,aspectjweaver
b、@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
Application.properties中spring.aop.auto的值是否等于true,没有默认为true
c、@EnableAspectJAutoProxy(proxyTargetClass = false)使用JdkDynamicAutoProxyConfiguration;
@EnableAspectJAutoProxy(proxyTargetClass = true)使用CglibAutoProxyConfiguration;
@EnableAspectJAutoProxy默认值是false,所以默认使用JdkDynamicAutoProxyConfiguration
d、在EnableAspectJAutoProxy上有@Import(AspectJAutoProxyRegistrar.class),将AspectJAutoProxyRegistrar加入到容器中
1、ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry调用了processConfigBeanDefinitions方法:
2、通过ConfigurationClassParser的parse方法,会将ImportBeanDefinitionRegistrar类型的bean加入到importBeanDefinitionRegistrars中;
3、ConfigurationClassBeanDefinitionReader的loadBeanDefinitionsForConfigurationClass方法-》loadBeanDefinitionsFromRegistrars方法;
4、AspectJAutoProxyRegistrar的registerBeanDefinitions方法;调用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
5、调用registerOrEscalateApcAsRequired方法将AnnotationAwareAspectJAutoProxyCreator注册到容器;
AbstractAutoProxyCreator继承ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor;
通过registerBeanPostProcessors方法将所有的BeanPostProcessor类型的实例添加到beanPostProcessors;
SmartInstantiationAwareBeanPostProcessor中的方法:
predictBeanType;重写
determineCandidateConstructors
getEarlyBeanReference重写
InstantiationAwareBeanPostProcessor中的方法:
postProcessBeforeInstantiation重写
postProcessAfterInstantiation
postProcessPropertyValues
BeanPostProcessor中的方法:
postProcessBeforeInitialization
postProcessAfterInitialization重写
2、在创建bean的过程中doCreateBean方法中下面这段源码:
AbstractAutoProxyCreator中实现了getEarlyBeanReference方法:
earlyProxyReferences这个map中缓存了早期代理的引用
targetSourcedBeans里如果包含这个bean,表示已经创建好了这个代理对象;
如果是基础设施的类或者原始的类,直接返回,并在第一次时缓存在advisedBeans中,value为false
通过AbstractAdvisorAutoProxyCreator的getAdvicesAndAdvisorsForBean方法获取到List
findCandidateAdvisors()就是把当前容器中的所有的Advisor都创建好,过滤、排序等操作
下面就该创建一个Proxy了,首先构造一个ProxyFactory,创建AopProxy
最终由要代理的类是不是接口类型或者Proxy决定用JDK的代理还是Cglib的
3、再说下@Aspect、@Pointcut、@Before等注解到底在哪里解析的?
获取切面类下没有标@Pointcut注解的方法,并按特定的顺序排序
获取切点表达式
最后返回一个Advisor的实现InstantiationModelAwarePointcutAdvisorImpl
在InstantiationModelAwarePointcutAdvisorImpl的都早函数中通过instantiateAdvice(this.declaredPointcut)方法去设置具体的Advice, 最终通过getAdvice方法实现
4、下面就是创建Proxy的时候如何利用Aop增强的?分别在jdk代理和cglib中