SpringAspectJ源码学习笔记
1概述
AOP现有两个主要的流行框架,即Spring AOP和Spring+AspectJ。前者SpringAOP使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供基于接口的代理,不支持类的代理。
AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
AOP(Aspect OrientedProgramming, 面向切面/方面编程) 旨在从业务逻辑中分离出来横切逻辑【eg:性能监控、日志记录、权限控制等】,提高模块化,即通过AOP解决代码耦合问题,让职责更加单一。
本节主要学习下基于注解的使用方式,首先看一下代码如何实现,接着基于源码剖析。
下图来源于网络
[图片上传失败...(image-496a8a-1617238323884)]
1.1AspectJ源码分析步骤
- EnableAspectJAutoProxy注解分析
- AopConfigUtils功能
- 代理对象BeanDefinition的产生时序
- 代理对象实例创建时序
- 业务方法的调用
2代码示例
2.1基于配置(本节不扩展)
2.2基于注解(重点)
2.2.1maven依赖
<!--springframework-->
<springframework.version>5.0.0.RELEASE</springframework.version>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>technicalskill</artifactId>
<groupId>com.kikop</groupId>
<version>1.0-SNAPSHOT</version>
<!--定义依赖的父pom文件-->
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>myspringaspectjdemo</artifactId>
<properties>
</properties>
<dependencies>
<!--1.techcommon-->
<dependency>
<groupId>com.kikop</groupId>
<artifactId>techcommon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--2.springframework-->
<!--2.spring对web的支持,依赖 spring-webmvc-->
<!--全家桶,此时jar包会自动下载(spring-context、spring-web、spring-webmvc)-->
<!--<dependency>-->
<!--<groupId>org.springframework</groupId>-->
<!--<artifactId>spring-webmvc</artifactId>-->
<!--<version>${springframework.version}</version>-->
<!--</dependency>-->
<!--2.1.spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<!--2.2.spring-context-support-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
</dependency>
<!--2.3.spring 动态代理依赖(aop 和 aspect)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
</dependency>
<!--2.4.spring-aspects内部依赖:aspectjweaver1.8.11,集成了aopalliance源码-->
<!--springframewrok4或单独使用aspectjweaver,需手动添加:aopalliance依赖包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${springframework.version}</version>
</dependency>
<!--2.5.spring test相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>
2.2.2定义业务服务类
package com.kikop.myspringaspectj.service;
import org.springframework.stereotype.Service;
/**
* @author kikop
* @version 1.0
* @project Name: myspringaspectjdemo
* @file Name: LogService
* @desc LogService
* @date 2021/3/31
* @time 10:50
* @by IDE: IntelliJ IDEA
*/
@Service(value = "logService")
public class LogService {
public LogService() {
}
public String getLogInfo() {
String result = "增加一个日志记录";
System.out.println(result);
return result;
}
}
2.2.3切面定义
package com.kikop.myspringaspectj.myaspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @author kikop
* @version 1.0
* @project Name: myspringaspectjdemo
* @file Name: MyLogAspect
* @desc MyLogAspect
* @date 2021/3/31
* @time 10:50
* @by IDE: IntelliJ IDEA
*/
// 注意点1
@Aspect
@Component
public class MyLogAspect {
/**
* 定义方法切点函数(设置需要拦截的范围)
*/
@Pointcut("execution(* com.kikop.myspringaspectj..*.*(..))")
private void myLogPointCut() {
}
/**
* 定义环绕增强逻辑
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("myLogPointCut()")
public Object invoke(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("begin log...");
Object result = proceedingJoinPoint.proceed();
System.out.println("end log.");
return result;
}
}
2.2.4配置定义
package com.kikop.myspringaspectj.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @author kikop
* @version 1.0
* @project Name: myspringaspectjdemo
* @file Name: AppConfig
* @desc AppConfig
* @date 2021/3/31
* @time 10:50
* @by IDE: IntelliJ IDEA
*/
@Configuration
@ComponentScan("com.kikop.myspringaspectj")
// 注意点2
// 开启AspectJ注解代理
@EnableAspectJAutoProxy
public class AppConfig {
}
2.2.5测试
package com.kikop.myspringaspectj;
import com.kikop.myspringaspectj.config.AppConfig;
import com.kikop.myspringaspectj.service.LogService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author kikop
* @version 1.0
* @project Name: myspringaspectjdemo
* @file Name: aspectjTest
* @desc aspectjTest
* @date 2021/3/31
* @time 10:50
* @by IDE: IntelliJ IDEA
*/
public class aspectjTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
LogService logService = annotationConfigApplicationContext.getBean("logService", LogService.class);
logService.getLogInfo();
}
}
输出如下:
begin log...
增加一个日志记录
end log.
3源码分析
3.1EnableAspectJAutoProxy注解分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
核心是这个注解引入了一个 @Import,value为AspectJ实现的一个ImportBeanDefinitionRegistrar,该接口需实现:registerBeanDefinitions,用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator。
/**
* Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
* AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry}
* as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
* @see EnableAspectJAutoProxy
*/
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
3.2AopConfigUtils功能
该Utils用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator。
// org\springframework\aop\config\AopConfigUtils.java
/**
* The bean name of the internally managed auto-proxy creator.
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
// 设置aop优先级最高(最小值)
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
3.3代理对象的BeanDefinition产生时序
3.3.1Step1_AnnotationConfigApplicationContext_refresh
SpringIOC容器启动时
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh(); //step1
}
// this();
// 构造 BeanDefinitionReader和BeanDefinitionScanner
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
3.3.2Step2_AbstractApplicationContext_invokeBeanFactoryPostProcessors
接着来到BeanFactoryPostProcessors后置处理器。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); //step2
3.3.3Step3_ConfigurationClassPostProcessor
PostProcessorRegistrationDelegate.java-->ConfigurationClassPostProcessor.java
获取所有的configClasses,用于后面遍历
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 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 {
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());
}
this.reader.loadBeanDefinitions(configClasses);
3.3.4Step4_ConfigurationClassBeanDefinitionReader
遍历configClass

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
/**
* Read a particular {@link ConfigurationClass}, registering bean definitions
* for the class itself and all of its {@link Bean} methods.
*/
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
TrackedConditionEvaluator trackedConditionEvaluator) {
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// ConfigurationClass: beanName 'appConfig', com.kikop.myspringaspectj.config.AppConfig
// 处理我们自定义的BeanDefinitionRegistrar
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
3.3.5Step5_registerBeanDefinitions
开始真正的BeanDefinition注册。
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
3.3.6Step6_AspectJAutoProxyRegistrar
走过千山万水,回来了,用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
3.4代理对象实例创建时序

3.4.1Step1_AbstractApplicationContext_finishBeanFactoryInitialization
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
3.4.2Step2_DefaultListableBeanFactory_preInstantiateSingletons
0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
2 = "org.springframework.context.annotation.internalRequiredAnnotationProcessor"
3 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
4 = "org.springframework.context.event.internalEventListenerProcessor"
5 = "org.springframework.context.event.internalEventListenerFactory"
6 = "appConfig"
7 = "myLogAspect"
8 = "logService"
9 = "org.springframework.aop.config.internalAutoProxyCreator"
// 这里我们以logService分析
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
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)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
((SmartFactoryBean<?>) factory).isEagerInit(),
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName); // go on
3.4.3Step3_AbstractBeanFactory_createBean
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
3.4.4Step4_AbstractAutowireCapableBeanFactory_createBean
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
3.4.5Step5_AbstractAutowireCapableBeanFactory_initializeBean
这里涉及Bean的声明周期
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//step1:BeanNameAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//step1:applyBeanPostProcessorsBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//step3:invokeInitMethods
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//step4:applyBeanPostProcessorsAfterInitialization
// Bean实例化后,检查其是否需要走aop代理(JDK或CGLIB),里面有复杂的判断逻辑
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
3.4.6Step6_AbstractAutowireCapableBeanFactory_applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 这里的 beanProcessor就是3.3中创建的:AnnotationAwareAspectJAutoProxyCreator
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);

3.4.7Step7_AbstractAutoProxyCreator_postProcessAfterInitialization
这里判断Bean实例对象是否需要代理
/**
* 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) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
getAdvicesAndAdvisorsForBean执行具体的判断逻辑,后续在结合execution执行主体进行深入分析。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
......
// Create proxy if we have advice.
// getAdvicesAndAdvisorsForBean进行具体的判断逻辑,参数:
// param1:com.kikop.myspringaspectj.service.LogService
// param2:logService
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;
}
// aop\framework\autoproxy\AbstractAdvisorAutoProxyCreator.java
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
3.4.8Step7_DefaultAopProxyFactory_createAopProxy
至此,LogService代理对象创建完成
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// targetClass:class com.kikop.myspringaspectj.service.LogService
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config); // 走JDK
}
return new ObjenesisCglibAopProxy(config); // 走CGLIG
}
else {
return new JdkDynamicAopProxy(config);
}
}
3.5业务方法调用流程
调用就很简单了。
网友评论