目录
前言
本文主要是@EnableAspectJAutoProxy注解开启AOP功能,以及通知的简单使用的源码流程介绍,代码比较多,已经与本流程关系不大的代码省略,减轻负担
一、项目介绍
1.项目主要类的代码
主启动类:
@SpringBootApplication
public class AopApplication {
public static void main(String[] args) {
ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(AopApplication.class, args);
MyService myService = configurableApplicationContext.getBean(MyService.class);
myService.showCompany();
}
}
Configuration配置类:
@Configuration
@EnableAspectJAutoProxy
public class MyConfig {
}
切面类:
/**AspectJAutoProxyRegistrar 是一个 ImportBeanDefinitionRegistrar
* AnnotationAwareAspectJAutoProxyCreator
* ->AspectJAwareAdvisorAutoProxyCreator
* ->AbstractAdvisorAutoProxyCreator
* ->AbstractAutoProxyCreator
* implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
*/
@Aspect
@Component
public class AspectClass {
@Pointcut("execution( * com.example.aop.service.*.*(..))")
public void point(){}
@Before("point()")
public void beforeMethod(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName() + "方法执行之前");
}
@After("point()")
public void afterMethod(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName() + "方法执行之后");
}
@AfterReturning(value = "point()", returning = "result")
public void returnMethod(JoinPoint joinPoint, Object result){
System.out.println(joinPoint.getSignature().getName() + "方法执行返回");
System.out.println("方法返回值" + result);
}
@AfterThrowing(value = "point()", throwing = "e")
public void throwMethod(JoinPoint joinPoint, Exception e){
System.out.println(joinPoint.getSignature().getName() + "方法执行异常");
System.out.println(e);
}
@Around("point()")
public void aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println(proceedingJoinPoint.getSignature().getName() + "环绕通知");
System.out.println("---------------");
proceedingJoinPoint.proceed();
System.out.println("---------------");
}
}
目标类:
@Service
public class MyService {
@Autowired
Company company;
public void showCompany(){
System.out.println(company.getName() + ": " + company.getAddress());
}
}
实体类:
@AllArgsConstructor
@NoArgsConstructor
@Data
@Component
public class Company {
@Value("Ali")
private String name;
@Value("SH")
private String address;
}
2.介绍@EnableAspectJAutoProxy注解的作用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
该注解通过@Import注解 将AspectJAutoProxyRegistrar注入到容器中
AspectJAutoProxyRegistrar 是一个ImportBeanDefinitionRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
..... //省略部分代码
}
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
该方法的作用:
如果容器中没有beanName为org.springframework.aop.config.internalAutoProxyCreator的BeanDefinition,则注册一个BeanDefinition.该BeanDefinition的beanClass是AnnotationAwareAspectJAutoProxyCreator.class
AnnotationAwareAspectJAutoProxyCreator.class该类的继承关系如下:
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator
->public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
->public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
-> abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
-> ...
由上可知该类是一个BeanPostProcessor的实现类,(重点,后面会提及)
SmartInstantiationAwareBeanPostProcessor的子类实现AbstractAutoProxyCreator 中有个方法postProcessAfterInitialization会返回一个代理对象
小结:如果这个ImportBeanDefinitionRegistrar
的实现类AspectJAutoProxyRegistrar被调用,会给容器注入一个BeanPostProcessor的一个实现类AnnotationAwareAspectJAutoProxyCreator的BeanDenifition,
beanName为org.springframework.aop.config.internalAutoProxyCreator
二、AOP使用流程介绍
1.AspectJAutoProxyRegistrar被调用的时机
首先看容器初始化过程的核心方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex)
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
当我们在主启动类main方法调用SpringApplication.run时会进行容器的初始化,以上是容器初始化的核心,这里我们着重看
invokeBeanFactoryPostProcessors(beanFactory);// 该方法会调用所有的BeanFactoryPostProcessor后置处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
...... //省略部分代码
}
调用的其实是 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//只有两个BeanFactoryPostProcessor
//SharedMetadataReaderFactoryContextInitializer下内部类CachingMetadataReaderFactoryPostProcessor
//ConfigurationWarningsApplicationContextInitializer下内部类 ConfigurationWarningsPostProcessor
//都实现了BeanDefinitionRegistryPostProcessor 不是关注重点
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//这里数组只有一个元素internalConfigurationAnnotationProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//注册一个beanName为internalConfigurationAnnotationProcessor的
//ConfigurationClassPostProcessor,该类是调用加载所有bean的关键
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry)方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
...... //省略部分代码
}
invokeBeanDefinitionRegistryPostProcessors代码如下:
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
//postProcessor只有一个 ConfigurationClassPostProcessor
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
最终会调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry)方法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
... //省略部分代码
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
processConfigBeanDefinitions该方法代码如下:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
.....//省略代码
// Parse each @Configuration class
//新建一个解析配置类的解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析启动类 这里candidates只有一个元素 就是主启动类
//也就是在这里 将主启动类包及其子包的类以BeanDefinition的形式注入到容器中(不是实例化)
//然后依次进行解析
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//调用配置类的特定方法 ImportBeanDefinitionRegistrar就是在这里被调用的
this.reader.loadBeanDefinitions(configClasses);
....... //省略部分代码
}
}
while (!candidates.isEmpty());
......
//省略部分代码
}
parser.parse(candidates)方法调用路径如下:
调用链:
ConfigurationClassParser.parse(Set<BeanDefinitionHolder> configCandidates)
->ConfigurationClassParser.parse(AnnotationMetadata metadata, String beanName)
->ConfigurationClassParser.processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter)
解析核心代码 sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
调用链:
doProcessConfigurationClass(configClass, sourceClass, filter)
->ConfigurationClassParser.doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
该方法会处理成员类,@PropertySource,@ComponentScan,@Import ,@ImportResource,@Bean等等
这里着重看@Import处理,代码如下:
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
//getImports(sourceClass)方法会获取这个类上的@Import注解,以及该类注解上的@Import注解导入的信息
调用链:
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
->ConfigurationClassParser.processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports)
核心代码:
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
//将ImportBeanDefinitionRegistrar 实例化,设置到所属的配置类中
会找到执行SpringApplication.run方法的主启动类,获取配置类上的注解
@SpringBootApplication 然后调用该注解下的所有方法等等;如果没有配置ComponentScan,则会取主启动类所在包为basePackages ,将该包及其子包的类信息放到一个集合Set中. (注意此时,只是BeanDefinition,不是实例化后的对象)
回到ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry)方法
//调用配置类的特定方法 ImportBeanDefinitionRegistrar就是在这里被调用的
this.reader.loadBeanDefinitions(configClasses);
调用链:
->ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(Set<ConfigurationClass> configurationModel);
核心代码:
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
->ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) ;
核心代码:
//调用类中实现了ImportBeanDefinitionRegistrar.registerBeanDefinitions
//AnnotationAwareAspectJAutoProxyCreator的BeanDefinition在这里诞生
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
AnnotationAwareAspectJAutoProxyCreator就是在此以BeanDefinition的方式加入到容器中
2.AnnotationAwareAspectJAutoProxyCreator 实例化
先回到spring的核心refresh()方法,前边执行的是 invokeBeanFactoryPostProcessors(beanFactory)方法;主要是调用工厂方法的后置处理器. 现在看看registerBeanPostProcessors(beanFactory).这个方法主要是将实现PriorityOrdered接口,
Ordered接口 的BeanPostProcessor 和剩余的BeanPostProcessor实例 按优先顺序加入到BeanFactory中
代码如下:
调用链:
registerBeanPostProcessors(beanFactory)
->PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获去BeanPostProcessor的BeanName
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//对BeanPostProcessor 按实现PriorityOrdered,Ordered接口以及其他进行分离
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//AnnotationAwareAspectJAutoProxyCreator 实现了Ordered接口(父类ProxyProcessorSupport实现了Ordered接口)
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
//创建AnnotationAwareAspectJAutoProxyCreator 实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//将AnnotationAwareAspectJAutoProxyCreator 实例加入到BeanFactory中
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
AnnotationAwareAspectJAutoProxyCreator 实现了Ordered接口(父类ProxyProcessorSupport实现了Ordered接口),通过 beanFactory.getBean(ppName, BeanPostProcessor.class)将AnnotationAwareAspectJAutoProxyCreator 实例化. 在此,我们已经知道了AnnotationAwareAspectJAutoProxyCreator实例创建的由来,接下来分析是怎么使用的
3.创建代理对象
回到spring初始化核心refresh()方法,现在看看finishBeanFactoryInitialization(beanFactory);
这个方法主要是实例化所有的非懒加载的单例bean
代码如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
......//省略部分代码
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有非懒加载的单例Bean
beanFactory.preInstantiateSingletons();
}
调用链:
beanFactory.preInstantiateSingletons();
-> DefaultListableBeanFactory.preInstantiateSingletons()
核心代码:
public void preInstantiateSingletons() throws BeansException {
...... //省略部分代码
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//挑出不是抽象的,并且是单例的,不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) { //如果是工厂类,则做一下处理
...... //省略部分代码
else {
getBean(beanName); //如果不是工厂类
}
}
}
...... //省略部分代码
}
这里我们重点关注getBean(beanName)这个方法, 这个方法就是用来实例化对象的.
调用链:
getBean(beanName);
->AbstractBeanFactory.Object getBean(String name);
->AbstractBeanFactory.doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
doGetBean方法的代码如下:
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
..... //省略部分代码
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
......//省略部分代码
// Create bean instance.
if (mbd.isSingleton()) { //如果是单例
sharedInstance = getSingleton(beanName, () -> {
try {
//实例化对象的核心
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
.....
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...... //省略部分代码
}
调用链:
getSingleton方法
->DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory);
getSingleton方法代码如下:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
..... //省略部分代码
//实例话对象的核心,其实就是调用刚刚传入的createBean(beanName, mbd, args)方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
..... 省略部分代码
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
singletonFactory.getObject() 其实就是调用 传入的匿名内部类中createBean(beanName, mbd, args)方法;
AbstractAutowireCapableBeanFactory.createBean方法代码如下:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......//省略部分代码
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
...//省略部分代码
}
doCreateBean方法代码如下:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//调用无参构造实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
...... //省略部分代码
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性赋值
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法 initMethod ...
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
...... //省略部分代码
return exposedObject;
}
这里我们着重看initializeBean(beanName, exposedObject, mbd)方法,虽然BeanDefinition已经实例化,这里会调用一些初始化方法,返回代理对象也是在这里返回的.
initializeBean方法代码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用实现了Aware接口的set方法 比如BeanFactoryAware 的set 方法(前提是实现了implements)
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用 AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用初始化方法
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()) {
//这里会调用AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
applyBeanPostProcessorsAfterInitialization该方法会调用AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization方法,该方法在父类AbstractAutoProxyCreator中,从而返回一个代理对象
postProcessAfterInitialization 代码如下:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//获取通知 前置,后置,环绕等等
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象,将通知一并放入代理对象中
//调用代理对象方法时,就会触发这些通知(切面中的那些方法)
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
至此 创建代理对象已经完成
4.调用代理对象方法,触发通知
当我们调用代理对象的目标方法时,首先会调用CglibAopProxy.intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)方法,代码如下:
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//获取拦截器链 也就是ExposeInvocationInterceptor,
//AspectJAroundAdvice,MethodBeforeAdviceInterceptor,AspectJAfterAdvice
//AfterReturningAdviceInterceptor,AspectJAfterThrowingAdvice
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
//创建MethodInvocation 然后调用其proceed()方法,如果目标方法有返回值 retVal负责接收
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
...... //省略部分代码
}
这里我们着重看new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
proceed()方法的调用:
调用链:
proceed()
->CglibAopProxy.proceed()
->调用父类ReflectiveMethodInvocation.proceed()方法
代码如下:
public Object proceed() throws Throwable {
//currentInterceptorIndex 初始值为-1
//interceptorsAndDynamicMethodMatchers 存储刚提到的6个拦截其器
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//调用目标方法
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
//调用拦截器的invoke方法 着重看这个
//注意this对象,就是创建的MethodInvocation,一直在拦截器中传递
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
简述下各个拦截器执行顺序:
首先是执行ExposeInvocationInterceptor.invoke(this);
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
//存储当前的MethodInvocation
invocation.set(mi);
try {
//调用目标方法的MethodInvocation.proceed()
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
调用链:
mi.proceed()
->CglibAopProxy.proceed()
->调用父类ReflectiveMethodInvocation.proceed()方法
又回到了父类ReflectiveMethodInvocation.proceed()方法,接下来执行的是AspectJAroundAdvice.invoke(this)
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
//调用通知方法
return invokeAdviceMethod(pjp, jpm, null, null);
}
调用链:
invokeAdviceMethod(pjp, jpm, null, null)
->AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t))
invokeAdviceMethodWithGivenArgs代码如下:
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
...... //省略部分代码
//调用@Around标注的方法
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
......//省略部分代码
}
调用切面类@Around标注的方法,该方法由用户实现,会调用ProceedingJoinPoint.proceed().
本人代码如下:
@Around("point()")
public void aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println(proceedingJoinPoint.getSignature().getName() + "环绕通知");
System.out.println("---------------");
proceedingJoinPoint.proceed();
System.out.println("---------------");
}
ProceedingJoinPoint是一个接口,这是实际使用的是它的子类MethodInvocationProceedingJoinPoint
proceed方法代码:
public Object proceed() throws Throwable {
//其实就是调用目标方法的proceed()方法
return this.methodInvocation.invocableClone().proceed();
}
又回到了父类ReflectiveMethodInvocation.proceed()方法,接下来执行的是MethodBeforeAdviceInterceptor.invoke(this)方法
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
//调用切面中用@Before注解标注的通知方法
//最终也是调用invokeAdviceMethodWithGivenArgs方法来调用通知方法的
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//调用目标方法
return mi.proceed();
}
又回到了父类ReflectiveMethodInvocation.proceed()方法,接下来执行的是AspectJAfterAdvice.invoke(this)方法
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//先执行目标方法
return mi.proceed();
}
finally {
//执行切面中用@After注解标注的通知方法
//最终也是调用invokeAdviceMethodWithGivenArgs方法来调用通知方法的
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
又回到了父类ReflectiveMethodInvocation.proceed()方法,接下来执行的是AfterReturningAdviceInterceptor.invoke(this)方法
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
//执行目标方法
Object retVal = mi.proceed();
//执行切面中使用@AfterReturning注解标注的通知方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
//返回目标方法的返回值
return retVal;
}
又回到了父类ReflectiveMethodInvocation.proceed()方法,接下来执行的是AspectJAfterThrowingAdvice.invoke(this)方法
代码如下:
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//执行目标方法
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
//如果报错,则执行切面中用@AfterThrowing注解标注的通知方法
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
//抛出错误 不再执行@AfterReturning标注的通知方法
throw ex;
}
}
又回到了父类ReflectiveMethodInvocation.proceed()方法,此时我们已经将所有的通知方法都走过了
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
满足条件,调用用通知方法
return invokeJoinpoint();
}
..... //省略部分代码
}
调用链:
invokeJoinpoint()
->CglibAopProxy.invokeJoinpoint()
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
//调用此方法,目标方法被调用
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
目标方法执行之后,就是调用链的收尾工作.如果不报错执行@AfterReturning标注的方法,如果报错则执行@AfterThrowing标注的方法,最后执行后置通知@After标注的方法, 环绕通知@Around方法的收尾部分
总结
当主启动类启动时,会调用refresh()方法,该方法是整个容器初始话的核心.在invokeBeanFactoryPostProcessors(beanFactory); 这里会调用我们使用@EnableAspectJAutoProxy 导入的AspectJAutoProxyRegistrar的registerBeanDefinitions方法,将AnnotationAwareAspectJAutoProxyCreator以BeanDefinition的形式(还没有实例化)加入到容器中,
在registerBeanPostProcessors(beanFactory);这里会将上一步生成的AnnotationAwareAspectJAutoProxyCreator实例化
在finishBeanFactoryInitialization(beanFactory);这里会将所有非抽象的,非懒加载的单实例bean实例化,代理对象就是在实例化过程中生成的
当我们从容器中获取对象,并调用目标方法时,就会调用相应的通知方法
通知方法执行顺序:是一个递归调用
ExposeInvocationInterceptor{
AspectJAroundAdvice{
MethodBeforeAdviceInterceptor{
AspectJAfterAdvice{
AfterReturningAdviceInterceptor{
AspectJAfterThrowingAdvice{
目标方法调用
}
}
}
}
}
}