1. 术语
在SpringAOP中,有很多专业术语,已经了解的小伙伴可以略过,不了解的朋友就需要注意看一下啦,不然会很懵的哟。
-
Aspect(切面)
跨多个类的关注点的模块化,与垂直调用的业务树不同,以横切的方式存在。
-
Join point(连接点)
程序执行过程的一个点,总是代表一个方法执行。
-
Advice (通知)
在特定连接点采取的行动,有Around、Before、After类型的Advice。
-
Pointcut(切入点)
匹配连接点的断言,Advice与切入点表达式相关联,并在切入点匹配的任何连接点处运行。切入点表达式匹配的连接点的概念是AOP的核心,Spring默认使用AspectJ切入点表达式语言。
-
Advisor(顾问)
Advisor是Advice的包装,其中PointcutAdvisor是Advice与Pointcut的包装,DefaultIntroductionAdvisor是Advice与IntroductionInfo的包装。
-
Introduction(引入)
可以将其他接口和实现动态引入到targetClass中。
-
Target object(目标对象)
将要被增强的对象。
-
AOP proxy(AOP代理)
由AOP框架为了实现切面功能而创建的对象,在Spring框架中,一个AOP代理是JDK动态代理或者CGLIB代理。
-
Weaving(织入)
将通知(Advice)切入连接点(Join point)的过程叫织入。
2 启用AOP
要使用SpringAOP,在SpringBoot项目中,需要在启动类使用一个EnableAspectJAutoProxy
注解。
以这个注解类为突破口,来看一下这个小小的注解为什么能提供这么大的作用。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
在这个注解中,使用@Import向当前IOC容器中引入了一个AspectJAutoProxyRegistrar
类。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@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);
}
}
}
}
这个类实现了ImportBeanDefinitionRegistrar
接口,所以在项目启动并执行BeanDefinitionRegistryPostProcessor
的时候,可以调用registerBeanDefinitions
方法来向IOC中注入BeanDefinition。
这里首先向IOC注册一个用于代理创建的类,再将注解中的属性设置到这个类的属性值中。
2.1 注册代理创建类
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
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);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
这个方法的主要作用就是向IOC容器注册一个名称为org.springframework.aop.config.internalAutoProxyCreator
的beanDefinition。
逻辑中会先判断当前IOC中是否含有一个名称为org.springframework.aop.config.internalAutoProxyCreator
的beanDefinition。
如果有,就根据优先级来对这个BeanDefinition的class进行修改,这里的直接影响就是后面实例化后,beanName为org.springframework.aop.config.internalAutoProxyCreator
的bean的class类型会改变。而这里的优先级是根据一个List判断的,
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
类在这个list中的位置越靠后,越优先使用。
如果没有,那就新建一个并注册到IOC中。
3. 代理创建类的处理
首先来看一下AnnotationAwareAspectJAutoProxyCreator
的类图:
可以看到,AnnotationAwareAspectJAutoProxyCreator
的继承关系为:
AnnotationAwareAspectJAutoProxyCreator
-> SmartInstantiationAwareBeanPostProcessor
-> InstantiationAwareBeanPostProcessor
-> BeanPostProcessor
所以注意的是,在bean的获取期间,可能会调用到的后置处理方法:
- SmartInstantiationAwareBeanPostProcessor
- getEarlyBeanReference
- InstantiationAwareBeanPostProcessor
- postProcessBeforeInstantiation
- postProcessAfterInstantiation
- BeanPostProcessor
- postProcessBeforeInitialization
- postProcessAfterInitialization
在这些后置处理方法中,AnnotationAwareAspectJAutoProxyCreator
重写了getEarlyBeanReference
、postProcessBeforeInstantiation
、postProcessAfterInitialization
这三个方法的逻辑,所以接下来我们将对这些方法来进行解析。
SmartInstantiationAwareBeanPostProcessor
是在从三级缓存中取对象时调用的,但是又并非每个bean的创建都要通过三级缓存的ObjectFactory的getObject去获取。
所以我们先对InstantiationAwareBeanPostProcessor
来进行说明。
3.1 InstantiationAwareBeanPostProcessor
AbstractAutoProxyCreator
对InstantiationAwareBeanPostProcessor
类中的 postProcessBeforeInstantiation
、postProcessAfterInitialization
方法进行了重写,我们来具体看下:
3.1.1 初始化前处理
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 生成beanName的缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
// beanName无值或者targetSourcedBeans不包含此bean
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 如果advisedBeans已经包含此值,则return
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 如果是一个基础类(Advice/Pointcut...)或者是一个“original instance”
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 放入advisedBeans并设置值为false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 找到自定义的TargetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
// targetSource不为空才走代理逻辑
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
// 添加到targetSourcedBeans集合
this.targetSourcedBeans.add(beanName);
}
// 获取所有Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 创建一个jdk/cglib代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
// 保存代理后的类class
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
细节解读
来对代码段进行解读,
Object cacheKey = getCacheKey(beanClass, beanName);
如果这个类是一个FactoryBean
,那就用这个将&+beanName
作为cacheKey,否则直接用beanName。
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
在beanName不为空,且不在targetSourcedBeans中的情况下,
-
如果advisedBeans包含了此cacheKey,就return null。
-
如果是infrastructureClass或者shouldSkip,那么将cacheKey作为key,Boolean.FALSE放入advisedBeans这个Map中,且return null。
怎样判断是否是infrastructureClass?
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
如果一个类是Advice
、Pointcut
、Advisor
、AopInfrastructureBean
的子类,那它就是一个infrastructureClass
。
怎样判断是否shouldSkip?
static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
if (!StringUtils.hasLength(beanName) || beanName.length() !=
beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
return false;
}
return (beanName.startsWith(beanClass.getName()) &&
beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
}
如果beanName为空或者beanName的长度不等于beanClass的name加上ORIGINAL_INSTANCE_SUFFIX
后缀的长度,那就不是originalInstance
。
如果beanName以beanClass的name开头,且以ORIGINAL_INSTANCE_SUFFIX
结尾的就是originalInstance。
这里我就有点疑惑,为什么不用equals直接去判断两者的值是否等,而是用长度判断后再用startsWith+endsWith去判断呢?
最后,如果是originalInstance,那就应该跳过。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
主要逻辑:
- 获取自定义的TargetSource。
- 将使用了TargetSource的beanName放入targetSourcedBeans。
- 获取并组装bean的Advice和Advisor信息。
- 创建代理对象
- 将cacheKey(基于beanName)和代理类的类信息保存到proxyTypes。
其中,getCustomTargetSource:
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// We can't create fancy target sources for directly registered singletons.
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
// Found a matching TargetSource.
if (logger.isTraceEnabled()) {
logger.trace("TargetSourceCreator [" + tsc +
"] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
可以看到,是从customTargetSourceCreators
变量中取出所有的TargetSourceCreator
,接着调用其getTargetSource
方法得到一个TargetSource
。如果说我们需要实现我们自己的TargetSource,那就需要自己创建一个TargetSourceCreator,然后放入到customTargetSourceCreators中。
其中,getAdvicesAndAdvisorsForBean
:
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 查找符合条件的Advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
这里就是找到所有符合条件的Advisor,如果为空,返回null,否则返回所有符合的Advisor。
findEligibleAdvisors
:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 查找所有候选的Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选出能被应用的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 扩展操作
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findCandidateAdvisors
:
在AnnotationAwareAspectJAutoProxyCreator
中重写了此方法:
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
这里首先是调用了父类的findCandidateAdvisors方法得到所有Advisor,其次再aspectJAdvisorsBuilder.buildAspectJAdvisors()
来添加Advisor。
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors:
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans:
public List<Advisor> findAdvisorBeans() {
// advisorNames缓存
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 在beanFactory中寻找Advisor
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 添加Advisor bean到advisors中
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
上述主要逻辑就是从beanFactory中获取Advisor bean。
继续分析this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
:
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 获取beanFactory中所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 判断是否应该跳过
if (!isEligibleBean(beanName)) {
continue;
}
// 获取bean的Class
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 如果这个bean被@Aspect所注解
if (this.advisorFactory.isAspect(beanType)) {
// 加入aspectNames集合
aspectNames.add(beanName);
// 生成AspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 默认为SINGLETON
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 查找Around/Before/After/AfterReturning/AfterThrowing注解的method,包装为Advisor
// 内部将Advice细分为BeforeAdvice、AfterAdvice等等
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
// 如果是singleton
if (this.beanFactory.isSingleton(beanName)) {
// 将所有Advisor放入缓存
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 非singleton则将factory放入缓存
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
// 到这里说明aspectNames有值,后续就走缓存逻辑
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
// 缓存中有值,说明是singleton,添加到advisors中
advisors.addAll(cachedAdvisors);
}
else {
// 非singleton,获取缓存中的factory,使用factory获取所有Advisor
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
// 添加到advisors中
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
回到主流程,其中createProxy
:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// 向其BeanDefinition中设置originalTargetClass属性
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
// 复制当前类中的proxyTargetClass、optimize、exposeProxy、frozen、opaque属性值
proxyFactory.copyFrom(this);
// proxyTargetClass值为true
if (proxyFactory.isProxyTargetClass()) {
// beanClass是Proxy的子类
if (Proxy.isProxyClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
// 向proxyFactory中添加beanClass的接口
proxyFactory.addInterface(ifc);
}
}
}
else {
// 如果BeanDefinition中preserveTargetClass属性为true
if (shouldProxyTargetClass(beanClass, beanName)) {
// 设置proxyTargetClass为true
proxyFactory.setProxyTargetClass(true);
}
else {
// 计算处理,接下来单独解析
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建所有Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 自定义操作proxyFactory
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 通过proxyFactory获取代理对象
return proxyFactory.getProxy(classLoader);
}
对于evaluateProxyInterfaces
方法:
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
// 不是配置类的回调接口且不是内部的语言接口且有定义方法
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// 向proxyFactory中添加interface
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
// 设置proxyTargetClass为true
proxyFactory.setProxyTargetClass(true);
}
判断是否是配置类的回调接口isConfigurationCallbackInterface
:
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
// 如果ifc是InitializingBean或者DisposableBean或者Closeable或者AutoCloseable或者是Aware的是实现类,那就是一个ConfigurationCallbackInterface
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
判断是否是内部的语言接口isInternalLanguageInterface
:
protected boolean isInternalLanguageInterface(Class<?> ifc) {
// name为"groovy.lang.GroovyObject"或者以".cglib.proxy.Factory"结尾或者以".bytebuddy.MockAccess"结尾
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}
上面很大一部分都是为了设置proxyTargetClass
与interface
,为的就是后续创建一个proxy对象。
proxyFactory.getProxy(classLoader)
中:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
首先createAopProxy()
使用来创建一个代理,里面实现了根据需要来创建JDK动态代理
还是CGLIB代理
,再通过getProxy
来创建一个具体的代理对象。
在createAopProxy
中:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
// 默认为DefaultAopProxyFactory
return this.aopProxyFactory;
}
DefaultAopProxyFactory#createAopProxy
:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// !NativeDetector.inNativeImage() 不是在image构建上下文且image运行时调用
// config.isOptimize() 代理是否应该执行主动优化
// config.isProxyTargetClass() 是否直接代理目标类以及任何接口
// hasNoUserSuppliedProxyInterfaces(config) 没有接口或只有一个SpringProxy的接口
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
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.");
}
// 目标类是一个接口或者是Proxy的子类或者是一个lamda表达式
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
// 返回jdk代理
return new JdkDynamicAopProxy(config);
}
// 返回cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 返回jdk代理
return new JdkDynamicAopProxy(config);
}
}
小结一下:如果不是在image构建上下文且image运行时调用且(代理是否应该执行主动优化或直接代理目标类以及任何接口或(没有接口或只有一个SpringProxy的接口))且目标类不是一个接口且不是Proxy的子类且不是一个lambda表达式,那么就使用CGLIB代理,其他情况使用JDK动态代理。
得到代理后,就是按情况调用其getProxy
方法来生成代理对象。
JdkDynamicAopProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
这里就是使用Proxy.newProxyInstance来创建代理对象,classLoader是类加载器,this.proxiedInterfaces是目标类的接口,this是一个InvocationHandler,也就是说JdkDynamicAopProxy是一个InvocationHandler的实现类,实现了invoke方法。
ObjenesisCglibAopProxy
ObjenesisCglibAopProxy继承自CglibAopProxy,并没有重写CglibAopProxy中的getProxy方法。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 得到目标类的class
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 如果目标类已经是一个代理类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// 获取目标类的父类(其实就是最原始的目标类)
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
// 向当前advice中添加当前目标类的接口
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 校验类中的method并根据log配置判断是否打印相关信息
validateClassIfNecessary(proxySuperClass, classLoader);
// new 一个Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置原始目标类
enhancer.setSuperclass(proxySuperClass);
// 设置被代理的接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
// 设置命名规则
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置用于从生成器创建字节码的策略
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 获取所有回调类(如MethodInterceptor)
Callback[] callbacks = getCallbacks(rootClass);
// 获取所有回调类的class
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// 用来判断具体该执行哪个回调
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
// 设置回调类class
enhancer.setCallbackTypes(types);
// 生成代理类的class并创建一个代理类实例对象
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
具体方法分析:
- AopProxyUtils.completeProxiedInterfaces
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
// 获取所有被代理的接口
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
// 没有实现的接口
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
// 如果目标类是一个接口
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
// 如果目标类是Proxy的子类或是一个lambda表达式
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
// +3是因为能确定在这里最多需要添加3个元素,防止ArrayList自动扩容引发性能问题(空间换时间)
List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
for (Class<?> ifc : specifiedInterfaces) {
// 适配jdk17中的密封接口
if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
proxiedInterfaces.add(ifc);
}
}
// isInterfaceProxied判断在advised的接口中是否有包含某个子类的接口
// 如果目标类的接口中不包含可指定为SpringProxy的类(SpringProxy、SpringProxy子类、SpringProxy实现类)
if (!advised.isInterfaceProxied(SpringProxy.class)) {
proxiedInterfaces.add(SpringProxy.class);
}
// 不应该阻止由此配置创建的代理被强制转换为Advice,且目标类的接口中不包含可指定为Advised的类
if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
proxiedInterfaces.add(Advised.class);
}
// 如果需要暴露DecoratingProxy,且目标类的接口中不包含可指定为DecoratingProxy的类
if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
proxiedInterfaces.add(DecoratingProxy.class);
}
return ClassUtils.toClassArray(proxiedInterfaces);
}
- getCallbacks
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// 调用时是否暴露代理对象,可通过AopContext这个ThreadLocal获取
boolean exposeProxy = this.advised.isExposeProxy();
// 配置是否被冻结
boolean isFrozen = this.advised.isFrozen();
// TargetSouce是否是static类型的
boolean isStatic = this.advised.getTargetSource().isStatic();
// aop带Adviced的拦截处理
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// 不带Adviced的拦截处理
Callback targetInterceptor;
// 暴露代理(运行时向AopContext这个ThreadLocal中暴露proxy对象)
if (exposeProxy) {
// 根据TargetSource的修饰符来判断使用哪个拦截器
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
// 根据TargetSource的修饰符来判断使用哪个拦截器
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// dispatcher
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
// 主要的callback
Callback[] mainCallbacks = new Callback[] {
aopInterceptor,
targetInterceptor,
new SerializableNoOp(),
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// 静态类&Advised被冻结
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
// 获取method匹配上的所有Advice
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
// 包装成FixedChainStaticTargetInterceptor
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
// 将method与索引x的关系保存进fixedInterceptorMap
this.fixedInterceptorMap.put(method, x);
}
// 将mainCallbacks与fixedCallbacks都放入callbacks中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
// 作为间隔索引,可以得知callbacks哪些是mainCallbacks,哪些是fixedCallbacks
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
- ProxyCallbackFilter
new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)
ProxyCallbackFilter
是通过其accept
方法来返回一个int值,这个值就作为下标
去callbacks数组中找到对应的callback进行执行。
首先看下CglibAopProxy中定义的index:
private static final int AOP_PROXY = 0;
private static final int INVOKE_TARGET = 1;
private static final int NO_OVERRIDE = 2;
private static final int DISPATCH_TARGET = 3;
private static final int DISPATCH_ADVISED = 4;
private static final int INVOKE_EQUALS = 5;
private static final int INVOKE_HASHCODE = 6;
再看看固定的callback:
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
下标对应起来就知道其代表的是哪个callback。
@Override
public int accept(Method method) {
if (AopUtils.isFinalizeMethod(method)) {
logger.trace("Found finalize() method - using NO_OVERRIDE");
// 是一个final方法,则不代理方法
return NO_OVERRIDE;
}
// 不应该阻止由此配置创建的代理被强制转换为Advice且该方法所属类是一个接口且该类是Advised的父类
if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if (logger.isTraceEnabled()) {
logger.trace("Method is declared on Advised interface: " + method);
}
// 应用dispatch callback
return DISPATCH_ADVISED;
}
// 如果是一个equals方法
if (AopUtils.isEqualsMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'equals' method: " + method);
}
// 应用invoke callback
return INVOKE_EQUALS;
}
// 如果是一个hashCode方法
if (AopUtils.isHashCodeMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'hashCode' method: " + method);
}
// 应用hashcode callback
return INVOKE_HASHCODE;
}
Class<?> targetClass = this.advised.getTargetClass();
// 获取该方法所有匹配的Advice
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
// 如果有匹配的Advice且配置未冻结
if (haveAdvice || !isFrozen) {
// 如果暴露代理
if (exposeProxy) {
if (logger.isTraceEnabled()) {
logger.trace("Must expose proxy on advised method: " + method);
}
// 应用aop callback
return AOP_PROXY;
}
// 如果是TargetSource是static类型,且冻结了配置且fixedInterceptorMap含有对此method的interceptor
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Method has advice and optimizations are enabled: " + method);
}
// 找到其interceptor的索引
int index = this.fixedInterceptorMap.get(method);
// 因为callbacks中是mainCallbacks + fixedCallbacks,而index是fixedCallbacks中的下标,fixedInterceptorOffset表示mainCallbacks的长度,所以在callbacks的下标即为index + this.fixedInterceptorOffset
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Unable to apply any optimizations to advised method: " + method);
}
// 其他情况使用aop callback
return AOP_PROXY;
}
}
else {
// See if the return type of the method is outside the class hierarchy of the target type.
// If so we know it never needs to have return type massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the correct one is already
// configured. If the target is not static, then we cannot use a dispatcher because the
// target needs to be explicitly released after the invocation.
// 暴露proxy或不是static类型
if (exposeProxy || !isStatic) {
// 应用target callback
return INVOKE_TARGET;
}
Class<?> returnType = method.getReturnType();
// 如果目标类可被声明为方法返回的类型
if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
if (logger.isTraceEnabled()) {
logger.trace("Method return type is assignable from target type and " +
"may therefore return 'this' - using INVOKE_TARGET: " + method);
}
// 应用target callback
return INVOKE_TARGET;
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Method return type ensures 'this' cannot be returned - " +
"using DISPATCH_TARGET: " + method);
}
// 应用dispatch target callback
return DISPATCH_TARGET;
}
}
}
这里得说一下根据method来找到Advice得逻辑,这里至关重要。
AddvicedSupport.getInterceptorsAndDynamicInterceptionAdvice
3.1.2 初始化后处理
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 生成缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果这个bean不存在于earlyProxyReferences中
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 有需要则执行代理逻辑
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
earlyProxyReferences
对象,是保存早期代理引用对象的一个Map
,如果这个bean被调用了从三级缓存中获取的方法,会调用SmartInstantiationAwareBeanPostProcessor
的getEarlyBeanReference
方法,AbstractAutoProxyCreator
实现了其getEarlyBeanReference
方法,在其中会将处理的bean放入earlyProxyReferences
这个Map中,且执行代理逻辑。所以在这里对earlyProxyReferences对象的操作,其实就是为了避免重复执行wrapIfNecessary代理逻辑。
细节解读
wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果这个bean是TargetSource,则不代理
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果已经存在于advisedBeans中,且值为false,则跳过代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是一个基础类(Advice/Pointcut...)或者是一个“original instance”
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 放入advisedBeans并设置值为false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取所有Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 放入advisedBeans并设置值为true
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建一个jdk/cglib代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 保存代理后的类class
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 放入advisedBeans并设置值为false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
知识点:
-
targetSourcedBeans这个Map是在InstantiationAwareBeanPostProcessor执行postProcessBeforeInstantiation方法的时候赋值的。
-
经过后置处理器的调用之后,advisedBeans这个Map中保存的是所有非TargetSource bean的是否生成代理类的关系。
3.2 SmartInstantiationAwareBeanPostProcessor
这个方法不一定能调用到,因为只有从三级缓存中根据ObjectFactory获取对象时才能走此逻辑,比如一个bean正在创建中,而另外一个bean又来获取这个正在创建中的bean。
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 生成缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 放入早期引用Map
this.earlyProxyReferences.put(cacheKey, bean);
// 有需要则执行代理逻辑
return wrapIfNecessary(bean, beanName, cacheKey);
}
wrapIfNecessary
的解析上面我们已经解析过,不再赘述。
4 执行
代理类已经创建好了,接下来就是调用这个代理类的方法。
大家都知道,JDK动态代理需要一个InvocationHandler、CGLIB需要一个MethodIntercepter来定义代理方法的具体执行逻辑。在
上述的代理过程中,我们通过JdkDynamicAopProxy或ObjenesisCglibAopProxy去产生一个代理对象,所以具体执行逻辑会不同,我们来分别看看。
4.1 JdkDynamicAopProxy
JDK动态代理的执行逻辑就是要实现一个InvocationHandler接口的invoke方法,JdkDynamicAopProxy本质就是一个InvocationHandler的是实现类,所以来看看这个方法的主要逻辑:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 自己未实现equals方法,且调用的是equals方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 自己未实现hashCode方法,且调用的是hashCode方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 获取最终的target Class
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 此method是一个继承自Advised的接口申明的方法
// 以反射执行
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// 向ThreadLocal暴露
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标类
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取匹配到该方法的所有inceptor
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果为空
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 直接反射执行连接点方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 包装成一个ReflectiveMethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 通过拦截方法列表一次执行,最终会执行连接点的方法得到返回值
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
4.2 ObjenesisCglibAopProxy
经过上面的处理,我们得到了所有的Callback,也得到了CallbackFilter,在调用方法时,就会经过CallbackFilter的accept方法得到callback的下标,再从callbacks数组中根据下标得到具体callback来执行。
我们来看看AOP中最常用的动态代理拦截器:
DynamicAdvisedInterceptor
@Override
@Nullable
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) {
// 如果需要暴露proxy,则设置到AopContext中
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);
// 获取method所有匹配的Advice
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 如果没有匹配的Advice,且是兼容的方法
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
// 对参数进行处理
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
try {
// 使用代理方法执行得到返回值
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
}
else {
// 如果有匹配的Advice,则进入CGLIB执行方法的特殊逻辑
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
对其中的方法进行说明:
-
CglibMethodInvocation.isMethodProxyCompatible
static boolean isMethodProxyCompatible(Method method) { return (Modifier.isPublic(method.getModifiers()) && method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) && !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method)); }
公开的,所属类不是Object,不是equals、hashCode、toString的方法就是兼容的方法。
-
AopProxyUtils.adaptArgumentsIfNecessary
static Object[] adaptArgumentsIfNecessary(Method method, @Nullable Object[] arguments) { if (ObjectUtils.isEmpty(arguments)) { return new Object[0]; } // 方法参数含有可变参数 if (method.isVarArgs()) { // 参数个数等于arguments中元素数量 if (method.getParameterCount() == arguments.length) { Class<?>[] paramTypes = method.getParameterTypes(); // 可变参数的index int varargIndex = paramTypes.length - 1; // 最后一个入参类型 Class<?> varargType = paramTypes[varargIndex]; // 最后一个参数是数组类型的(此处为可变参数) if (varargType.isArray()) { // 获取arguments中对应的参数值 Object varargArray = arguments[varargIndex]; // 如果varargArray是一个数组且varargArray不是可变参数对应类型的实例 if (varargArray instanceof Object[] && !varargType.isInstance(varargArray)) { Object[] newArguments = new Object[arguments.length]; // 将arguments中可变参数的值复制到newArguments中,此时newArguments就一个值,这个值是数组类型的 System.arraycopy(arguments, 0, newArguments, 0, varargIndex); // 获取可变参数的类型 Class<?> targetElementType = varargType.getComponentType(); int varargLength = Array.getLength(varargArray); // 创建一个类型为可变内部参数类型,长度为可变参数值个数的数组 Object newVarargArray = Array.newInstance(targetElementType, varargLength); // 复制可变参数值到newVarargArray中,此时newVarargArray元素个数为可变参数值个数 System.arraycopy(varargArray, 0, newVarargArray, 0, varargLength); newArguments[varargIndex] = newVarargArray; return newArguments; } } } } return arguments; }
-
new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed()
这里分为两部分,首先是创建一个
CglibMethodInvocation
对象,其次调用其proceed
方法。public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { // 调用父类方法将传入的值设置进实例的变量中 super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); // 赋值methodProxy this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null); }
public Object proceed() throws Throwable { // 如果当前正在执行的拦截方法是列表的最后一个,那说明应该去指定joinPoint if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // currentInterceptorIndex初始值为-1,这里最开始是获取的第一个拦截方法 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. 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 { // 如果是一个拦截器,则直接执行 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
在这里,就会执行@Before、@After、@Around等注解的方法。