相关阅读
- Spring Boot源码简析 @EnableAspectJAutoProxy
- Spring AOP基础组件 Advice
- Spring AOP基础组件 Advisor
- Spring AOP基础组件 AopProxy
- Spring AOP基础组件 AopProxyFactory
- Spring AOP基础组件 AbstractAutoProxyCreator
简介
本文基于SpringBoot 2.6.2
对@Aspect
注解的使用进行源码分析。
Demo
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
源码
业务接口及实现
public interface IDemoService {
String method();
}
@Service
@Slf4j
public class DemoServiceImpl implements IDemoService {
@Override
public String method() {
log.info("do something...");
return "method's result";
}
}
切面逻辑
@Aspect
@Component
@Slf4j
public class LogAspect {
@Pointcut(value = "execution(* *.*(..))")
public void pointcut() {
}
/**
* 前置通知,目标方法之前执行
*
* @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
*/
@Before(value = "pointcut()")
public void before(JoinPoint joinPoint) {
log.info("Before {}", joinPoint.getSignature().getName());
}
/**
* 后置通知,目标方法之后执行,无论目标方法正常返回或者异常退出都会执行
*
* @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
*/
@After(value = "pointcut()")
public void after(JoinPoint joinPoint) {
log.info("After {}", joinPoint.getSignature().getName());
}
/**
* 返回后通知,目标方法正常返回后执行
*
* @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
*/
@AfterReturning(value = "pointcut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
log.info("AfterReturning {}", joinPoint.getSignature().getName());
log.info("AfterReturning JoinPoint's result is : {}", result);
}
/**
* 异常通知,目标方法发生指定异常(方法入参)退出后执行
*
* @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
*/
@AfterThrowing(value = "pointcut()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, IllegalArgumentException e) {
log.info("AfterThrowing {}", joinPoint.getSignature().getName());
log.info("AfterThrowing Throwable is : {}", e.getMessage());
}
/**
* 环绕通知
* 方法需要有返回结果,可以直接返回目标方法执行的结果,也可以返回基于目标方法执行结果的逻辑处理后结果
* @param joinPoint 连接点类型必须为ProceedingJoinPoint,允许控制何时执行,是否执行连接点
* @return 返回值
*/
@Around(value = "pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("Around before {}", joinPoint.getSignature().getName());
Object result;
try {
// 执行连接点
result = joinPoint.proceed();
} catch (Throwable e) {
log.info("Around Throwable : {}", e.getMessage());
return null;
}
log.info("Around after {}", joinPoint.getSignature().getName());
log.info("Around JoinPoint's result is : {}", result);
// 返回连接点的返回结果
return result;
}
}
测试
代码
@SpringBootTest
class DemoServiceTest {
@Autowired
private DemoServiceImpl demoService;
@Test
void test() {
demoService.method();
}
}
测试结果
- 正常退出
方法实现如下:
@Override
public String method() {
log.info("do something...");
return "method's result";
}
结果如下:
Around before method
Before method
do something...
AfterReturning method
AfterReturning JoinPoint's result is : method's result
After method
Around after method
Around JoinPoint's result is : method's result
- 异常退出且匹配异常通知方法
方法实现如下:
@Override
public String method() {
log.info("do something...");
throw new IllegalArgumentException("Invalid argument");
}
结果如下:
Around before method
Before method
do something...
AfterThrowing method
AfterThrowing Throwable is : Invalid argument
After method
Around Throwable : Invalid argument
- 异常退出且未匹配异常通知方法
方法实现如下:
@Override
public String method() {
log.info("do something...");
throw new IllegalStateException("Invalid state");
}
结果如下:
Around before method
Before method
do something...
After method
Around Throwable : Invalid state
简析
自动配置
通过依赖spring-boot-starter-aop
,会引入如下依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.14</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
<scope>compile</scope>
</dependency>
SpringBoot的自动配置模块会根据spring-boot-autoconfigure-2.6.2.jar
下的spring.factories
文件自动引入自动配置类XxxAutoConfiguration
,其中就包括org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
;
AopAutoConfiguration
简介
AopAutoConfiguration
完成了Spring AOP的自动配置功能;支持设置配置项spring.aop.auto
来开启(true,默认值)或者关闭(false)自动配置;支持设置配置项spring.aop.proxy-target-class
来表示使用CGLIB代理(true,默认值)还是JDK动态代理(false);
源码
@Configuration(proxyBeanMethods = false)
// 除非明确配置spring.aop.auto=false,否则开启AOP自动配置
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration(proxyBeanMethods = false)
// 存在org.aspectj.weaver.Advice则生效
// 因为存在org.aspectj.aspectjweaver依赖,故org.aspectj.weaver.Advice存在
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
@Configuration(proxyBeanMethods = false)
// 引入EnableAspectJAutoProxy,开启@Aspect注解驱动的自动代理的功能,且使用JDK动态代理
@EnableAspectJAutoProxy(proxyTargetClass = false)
// 若配置spring.aop.proxy-target-class=false,则生效
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
// 引入EnableAspectJAutoProxy,开启@Aspect注解驱动的自动代理的功能,且使用CGLIB代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
// 除非明确配置spring.aop.proxy-target-class=false,否则生效
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
static class CglibAutoProxyConfiguration {
}
}
@Configuration(proxyBeanMethods = false)
// 不存在org.aspectj.weaver.Advice则生效
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
// 除非明确配置spring.aop.proxy-target-class=false,否则生效
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
static class ClassProxyingConfiguration {
@Bean
static BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {
return (beanFactory) -> {
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
};
}
}
}
由于配置文件中未设置配置项spring.aop.auto
,则存在依赖org.aspectj.aspectjweaver
,所以AopAutoConfiguration.AspectJAutoProxyingConfiguration
会生效,又因为配置文件中未设置配置项spring.aop.proxy-target-class
,所以AopAutoConfiguration.AspectJAutoProxyingConfiguration.CglibAutoProxyConfiguration
会生效,引入@EnableAspectJAutoProxy
,且其proxyTargetClass
为true,表示使用CGLIB代理;
EnableAspectJAutoProxy
简介
@EnableAspectJAutoProxy
表示开启@Aspect
注解驱动的自动代理的功能,即向容器添加自动代理创建器AnnotationAwareAspectJAutoProxyCreator
,详见Spring Boot源码简析 @EnableAspectJAutoProxy
切面解析
这块主要分析被@Aspect
标注的类的通知方法是如何转换为Advisor
;
AnnotationAwareAspectJAutoProxyCreator
重写了父类AbstractAdvisorAutoProxyCreator
的findCandidateAdvisors
方法,代码如下:
protected List<Advisor> findCandidateAdvisors() {
// 调用父类方法获取已有的Advisor集合
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
// 增加额外的Aspect Advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
AnnotationAwareAspectJAutoProxyCreator
的属性aspectJAdvisorsBuilder
使用的是BeanFactoryAspectJAdvisorsBuilderAdapter
;
BeanFactoryAspectJAdvisorsBuilderAdapter
其buildAspectJAdvisors
方法代码如下:
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
// 如果还未解析过@Aspect标注的类,则需要解析
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
// Double Check
if (aspectNames == null) {
// 开始解析
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 获取容器中所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历beanName
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
// 若不符合,则跳过
// 默认实现都符合,子类可重写以实现额外处理逻辑
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 判断是否被标注@Aspect
if (this.advisorFactory.isAspect(beanType)) {
// 找到被@Aspect标注的bean,则缓存该beanName
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 如果是单例,则通知方法是通用的
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析该bean的所有通知方法,并包装为Advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// bean是单例,表示Advisor可通用,则缓存所有Advisor
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// bean是多例,表示Advisor需要每次生成,则缓存该factory
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
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);
// 缓存该factory
this.aspectFactoryCache.put(beanName, factory);
// 解析该bean的所有通知方法,并包装为Advisor
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
// 缓存解析结果
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
// 不存在@Aspect标注的类,则无通知方法
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
// 遍历缓存的@Aspect标注的beanName
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
// 存在缓存的Advisor则表示为单例,可以直接使用
advisors.addAll(cachedAdvisors);
}
else {
// 不存在,则需要每次重新生成
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
其中this.advisorFactory.getAdvisors(factory)
负责将Aspect类型注解标注的通知方法变成Advisor
,其this.advisorFactory
为ReflectiveAspectJAdvisorFactory
;
ReflectiveAspectJAdvisorFactory
其getAdvisors
方法代码如下:
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 遍历所有通知方法,即非@Pointcut标注的,非源自Object的方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 将通知方法转换为Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
// 转换成功则添加该Advisor
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// 查找引介通知
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
// 存在则添加该Advisor
advisors.add(advisor);
}
}
return advisors;
}
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获取Pointcut表达式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
// 不存在则不是通知方法
return null;
}
// 将通知方法包装为InstantiationModelAwarePointcutAdvisorImpl
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
InstantiationModelAwarePointcutAdvisorImpl
的instantiateAdvice
方法会根据AspectJExpressionPointcut
获取到真正的Advice
,代码如下:
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
使用this.aspectJAdvisorFactory
即ReflectiveAspectJAdvisorFactory
,将方法包装为Advice
,其getAdvice
代码如下:
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
// 获取通知方法上的Aspect类型注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 校验当前方法所在的类是否被@Aspect标注
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
// 根据Aspect注解类型,包装为对应的Advice
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
至此,@Aspect
标注的类中的通知方法转化为Advisor
的分析就结束了;
代理创建
这块主要分析实例是如何被代理的;
AnnotationAwareAspectJAutoProxyCreator
继承自AbstractAutoProxyCreator
,AbstractAutoProxyCreator
实现了SmartInstantiationAwareBeanPostProcessor
接口,所以AnnotationAwareAspectJAutoProxyCreator
可以在Bean实例之前做处理,比如创建代理来替换原Bean;
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) {
// 如果该Bean存在相应的Advisor的话,则代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
// TargetSource无需包装
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;
}
// 获取特定于Bean的拦截器,如果为null则无需代理
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;
}
getAdvicesAndAdvisorsForBean
方法由AbstractAdvisorAutoProxyCreator
实现,核心代码如下:
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();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取BeanFactory中所有的Advisor Bean
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 获取可以应用到指定Bean的Advisor Bean
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 扩展Advisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 借助BeanFactoryAdvisorRetrievalHelper实现获取BeanFactory中所有的Advisor Bean
return this.advisorRetrievalHelper.findAdvisorBeans();
}
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 借助AopUtils获取可以应用到指定Bean的Advisor Bean
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
在切面解析中提到,AnnotationAwareAspectJAutoProxyCreator
重写了父类AbstractAdvisorAutoProxyCreator
的findCandidateAdvisors
方法,支持@Aspect
标注的类中的通知方法转化的Advisor
,所以只要满足Aspect注解中的pointcut表达式的方法所在的类都会被代理;
AbstractAutoProxyCreator.createProxy
实现了代理创建,其核心代码如下:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
// 处理引介通知
if (Proxy.isProxyClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// 未设置proxyTargetClass标识,则进行默认检查
if (shouldProxyTargetClass(beanClass, beanName)) {
// 设置proxyTargetClass标识
proxyFactory.setProxyTargetClass(true);
}
else {
// 评估是否有可用的代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 根据通用拦截器和特定拦截器创建Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 可由子类实现定制化处理
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
// 设置preFiltered标识,表示拦截器都有效
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 通过ProxyFactory创建代理
return proxyFactory.getProxy(classLoader);
}
ProxyFactory.getProxy
方法的核心代码如下:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
其中createAopProxy()
最终由DefaultAopProxyFactory
实现,核心代码如下:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// 1. 设置`optimize`标识;
// 2. 设置`proxyTargetClass`标识;
// 3. 没有指定任何代理接口;
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)) {
// 如果目标对象为接口类型或者目标对象类型为动态代理类,则使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
ObjenesisCglibAopProxy
通过自动配置可知proxyTargetClass为true,即使用CGLIB代理——ObjenesisCglibAopProxy
;
ObjenesisCglibAopProxy
的getProxy
方法继承自父类CglibAopProxy
,核心代码如下:
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 目标对象类型必须有效,CGLIB是基于类进行代理
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)) {
// 目标对象类型是CGLIB创建的类型
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 校验目标类型的final方法
validateClassIfNecessary(proxySuperClass, classLoader);
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));
// 获取方法回调
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// ProxyCallbackFilter决定method通过哪一个Callback回调
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 根据方法回调创建代理类并创建代理类的实例
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);
}
}
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
// 有构造参数则使用
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 用于处理有Advice chain的方法的调用
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// 用于处理没有Advice chain且可以返回this的方法的调用
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// 用于处理没有Advice chain且不可以返回this的方法的调用
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
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,
// 处理equals方法调用
new EqualsInterceptor(this.advised),
// 处理hashCode方法调用
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// 如果目标对象是静态的,且Advice chain不支持变动,则可以对方法调用做出优化
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
// 使用FixedChainStaticTargetInterceptor处理方法的调用
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
// 记录FixedChainStaticTargetInterceptor起始位置
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
JdkDynamicAopProxy
如果使用JDK动态代理,即JdkDynamicAopProxy
,其核心代码如下:
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 通过Proxy创建代理,将自身作为InvocationHandler传入
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
至此,代理创建的分析就结束了;
代理方法执行
ObjenesisCglibAopProxy
通过自动配置可知,使用的是CGLIB代理,即ObjenesisCglibAopProxy
,代理方法的执行是通过Enhancer
的Callback机制实现的,在创建CGLIB代理时,会准备代理方法的Callback,然后设置到Enhancer
中,代码如下:
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
// 有构造参数则使用
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
JdkDynamicAopProxy
如果使用JDK动态代理,JdkDynamicAopProxy
实现了InvocationHandler
接口,代理方法的执行的入口是invoke
,核心代码如下:
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方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 没有实现hashCode方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// DecoratingProxy只定义了getDecoratedClass方法
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
// 代理可以转换为Advised,通过反射执行方法
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// 暴露当前代理
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// 没有配置拦截器,则通过反射,直接使用目标对象执行方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 使用配置的拦截器链创建MethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// MethodInvocation执行时,会先执行完拦截器的逻辑,最后才使用目标对象执行方法
retVal = invocation.proceed();
}
// 处理方法的返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// 如果方法返回值为自身,则修正为代理
// 但无法做到当返回值持有自身的一个引用时,将引用修正为代理
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()) {
// 释放目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// 恢复当前上下文的代理
AopContext.setCurrentProxy(oldProxy);
}
}
}
至此,代理方法执行的分析就结束了。