AOP
- AOP基本概念
- AOP流程
- AOP调用位置
- 源码分析
- 1. AbstractAutowireCapableBeanFactory#initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
- 2. AbstractAutoProxyCreator#postProcessAfterInitialization(@Nullable Object bean, String beanName)
- 3. AbstractAutoProxyCreator#wrapIfNecessary(Object bean, String beanName, Object cacheKey)
- 4. AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)
- 5. AbstractAdvisorAutoProxyCreator#findEligibleAdvisors(Class<?> beanClass, String beanName)
- 6. AnnotationAwareAspectJAutoProxyCreator#buildAspectJAdvisors()
- 7. BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
- 8. ReflectiveAspectJAdvisorFactory#getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory)
- 9. ReflectiveAspectJAdvisorFactory#getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName)
- 10. ReflectiveAspectJAdvisorFactory#getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass)
- 11. AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod(Method method)
- 12. AbstractAspectJAdvisorFactory#AspectJAnnotation(A annotation)
- 13.回到第9步 ReflectiveAspectJAdvisorFactory#getAdvisor()
- 14. InstantiationModelAwarePointcutAdvisorImpl#new InstantiationModelAwarePointcutAdvisorImpl()
- 15. InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice(AspectJExpressionPointcut pointcut)
- 16. ReflectiveAspectJAdvisorFactory#getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName)
- 17. 回到第13步 ReflectiveAspectJAdvisorFactory#getAdvisor()
- 18. 回到第3步AbstractAutoProxyCreator#wrapIfNecessary()
- 19. AbstractAutoProxyCreator#createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource)
- 20. AbstractAutoProxyCreator#buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors)
- 21. AbstractAutoProxyCreator#resolveInterceptorNames()
- 22. 回到第20步AbstractAutoProxyCreator#buildAdvisors()方法,DefaultAdvisorAdapterRegistry#wrap(Object adviceObject)
- 23. 回到第19步 AbstractAutoProxyCreator#createProxy(),ProxyFactory#getProxy(@Nullable ClassLoader classLoader)
- 24. JdkDynamicAopProxy#getProxy(@Nullable ClassLoader classLoader)
- 25. JdkDynamicAopProxy#invoke(Object proxy, Method method, Object[] args)
- 26. AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass)
- 27. DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass)
- 28. DefaultAdvisorAdapterRegistry#getInterceptors(Advisor advisor)
- 29. 回到第25步 JdkDynamicAopProxy#invoke(),ReflectiveMethodInvocation#ReflectiveMethodInvocation()
- 30. ReflectiveMethodInvocation#proceed()
- 31. AspectJAroundAdvice#invoke(MethodInvocation mi)
- 32. AspectJAroundAdvice#invoke(MethodInvocation mi)
- 添加一个全局AOP
- 总结
AOP基本概念
1)连接点(Joinpoint)
程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。
2)切点(Pointcut)
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物。AOP通过“切点”定位特定的连接点。连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责切点所设定的查询条件,找到对应的连接点。其实确切地说,不能称之为查询连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。
3)增强(Advice)
增强是织入到目标类连接点上的一段程序代码,在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点方位信息和切点信息,我们就可以找到特定的连接点。
4)目标对象(Target)
增强逻辑的织入目标类。如果没有AOP,目标业务类需要自己实现所有逻辑,而在AOP的帮助下,目标业务类只实现那些非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。
5)引介(Introduction)
引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
6)织入(Weaving)
织入是将增强添加对目标类具体连接点上的过程。AOP像一台织布机,将目标类、增强或引介通过AOP这台织布机天衣无缝地编织到一起。根据不同的实现技术,AOP有三种织入的方式:
a、编译期织入,这要求使用特殊的Java编译器。
b、类装载期织入,这要求使用特殊的类装载器。
c、动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
7)代理(Proxy)
一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。
8)切面(Aspect)
切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
AOP流程
1、advisor:可以理解为一个pointCut和一个advice的封装,是一个切面;
2、AspectJAwareAdvisorAutoProxyCreator,当实例化所有bean都会执行到AspectJAwareAdvisorAutoProxyCreator类,它会检测bean是否advisor以及advice存在,如果有就说明这个bean有切面,有切面那么就会生成代理;
3、jdk的代理,bean里面的所有advisor加入到proxyFactory;
4、jdkDynamicProxy invoke,拿到bean里面的所有Interceptor,会循环proxyFactory里面的所有advisor
的advice,里面的advice有两种类型,要么是advice,要么是MethodInterceptor类型的;
5、代理对象调用方式,是一个MethodInterceptor类型的类的链式调用过程,直到容器的大小和索引一致的时候调用JoinPoint目标方法。
AOP调用位置
- 在bean实例化+ioc依赖注入完成以后调用aop的方法,如果bean还没有实例化完成,就不能被代理。
- 通过bean的实例化过程分析,bean实例化+ioc依赖注入之后的方法是AbstractBeanFactory#initializeBean(beanName, exposedObject, mbd)
后面断点调试的代码示例https://blog.csdn.net/qq_40977118/article/details/108937745
源码分析
1. AbstractAutowireCapableBeanFactory#initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//这个地方可能生出代理实例,是aop的入口
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. AbstractAutoProxyCreator#postProcessAfterInitialization(@Nullable Object bean, String beanName)
3. AbstractAutoProxyCreator#wrapIfNecessary(Object bean, String beanName, Object cacheKey)
- 如果这个bean有advice的话,就创建当前bean的代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//创建当前bean的代理,如果这个bean有advice的话,重点看,重要程度5
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果有切面,则生成该bean的代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//把被代理对象bean实例封装到SingletonTargetSource对象中
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
4. AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)
- 找到合格的切面
5. AbstractAdvisorAutoProxyCreator#findEligibleAdvisors(Class<?> beanClass, String beanName)
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//找到候选的切面,其实就是一个寻找有@Aspect注解的过程,把工程中所有有这个注解的类封装成Advisor返回
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//对有@Order@Priority进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
- 进入子类
6. AnnotationAwareAspectJAutoProxyCreator#buildAspectJAdvisors()
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;
}
7. BeanFactoryAspectJAdvisorsBuilder#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<>();
// 1.获取spring容器中的所有bean的名称BeanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 2.判断类上是否有@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
// 3.把带有@Aspect注解的类的基本信息包装成AspectMetadata对象
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 4.创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 5.创建切面advisor对象
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
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<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
8. ReflectiveAspectJAdvisorFactory#getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory)
- 创建切面advisor对象
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 1.从工厂中获取有@Aspect注解的类Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//从工厂中获取有@Aspect注解的类的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// 2.创建工厂的装饰类,获取实例只会获取一次
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 3.这里循环没有@Pointcut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 4. 得到Advisor对象(包含Pointcut和Advice)非常重要,重要程度 5
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
// 5.把Advisor对象加入容器
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
//判断属性上是否有引介注解
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
//判断属性上是否有DeclareParents注解,如果有返回切面
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
9. ReflectiveAspectJAdvisorFactory#getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName)
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;
}
//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
//这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
10. ReflectiveAspectJAdvisorFactory#getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass)
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//从候选的增强方法里面 candidateAdviceMethod 找有有注解
//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//并把注解信息封装成AspectJAnnotation对象
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
11. AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod(Method method)
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
//找到Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//注解的方法,并且把注解里面的信息封装成AspectJAnnotation对象
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
//找的规则就是找注解的父注解,递归的方式去找,直到找到目标注解为止
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
//把注解里面的信息解析出来,然后包装成AspectJAnnotation对象
return new AspectJAnnotation<>(result);
}
else {
return null;
}
}
- 找到带@Pointcut,@Around,@Before,@After,@AfterReturning,@AfterThrowing的注解
12. AbstractAspectJAdvisorFactory#AspectJAnnotation(A annotation)
- 封装了注解里面的基本信息,注解本身,注解类型,参数,表达式,最后返回
public AspectJAnnotation(A annotation) {
this.annotation = annotation;
//得到注解的类型
this.annotationType = determineAnnotationType(annotation);
try {
//解析注解上面的表达式,如@Around("pc1()")
//@AfterReturning(pointcut = "execution(public * com.xiangxue.jack.service.*.*(..))")
this.pointcutExpression = resolveExpression(annotation);
//获取注解上的参数
Object argNames = AnnotationUtils.getValue(annotation, "argNames");
this.argumentNames = (argNames instanceof String ? (String) argNames : "");
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
}
}
13.回到第9步 ReflectiveAspectJAdvisorFactory#getAdvisor()
14. InstantiationModelAwarePointcutAdvisorImpl#new InstantiationModelAwarePointcutAdvisorImpl()
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
//这个方法重点看看,创建advice对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
15. InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice(AspectJExpressionPointcut pointcut)
- 创建advice对象
- Advice是一个空的接口,用来区分类型
16. ReflectiveAspectJAdvisorFactory#getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName)
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取有@Aspect注解的类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
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;
//根据不同的注解类型创建不同的advice类实例
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
//实现了MethodInterceptor接口
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
//实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
//实现了MethodInterceptor接口
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
//实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
//实现了MethodInterceptor接口
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);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//计算argNames和类型的对应关系
springAdvice.calculateArgumentBindings();
return springAdvice;
}
17. 回到第13步 ReflectiveAspectJAdvisorFactory#getAdvisor()
- 通过构造方法InstantiationModelAwarePointcutAdvisorImpl得到了Pointcut和Advice
18. 回到第3步AbstractAutoProxyCreator#wrapIfNecessary()
- 如果这个bean有advice的话,创建当前bean的代理
- 接下来看代理对象是怎么创建的
19. AbstractAutoProxyCreator#createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource)
- 工厂模式创建代理
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);
}
// 1.创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 2.proxyTargetClass这个默认就是false,false使用jdk动态代理,true使用cglib动态代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
//proxyTargetClass 是否对类进行代理,而不是对接口进行代理,设置为true时,使用CGLib代理。
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 3.把advice类型的增强包装成advisor切面(specificInterceptors是上一步找到的合格的切面)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 4.把advisors(切面)和targetSource(被代理对象)赋值给代理工厂对象
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
// 5.用来控制代理工厂被配置后,是否还允许修改代理的配置,默认为false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 6.获取代理实例
return proxyFactory.getProxy(getProxyClassLoader());
}
20. AbstractAutoProxyCreator#buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors)
- 扩展interceptorNames属性
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
//自定义MethodInterceptor.拿到AnnotationAwareAspectJAutoProxyCreator对象调用setInterceptorNames方法
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
//对自定义的advice要进行包装,把advice包装成advisor对象,切面对象
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
21. AbstractAutoProxyCreator#resolveInterceptorNames()
- 可以自己创建一个实现了MethodInterceptor接口的类,把类的beanName添加到InterceptorNames中,把这个类封装成beanDefiniton注册到spring容器,对应的名称是AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME,就可以做全局拦截了,文章最后演示
- 提供了set方法
- 创建一个实现了MethodInterceptor接口的类,把这个类包装成Advisor加入Advisor[]数组中
- advice是传进来的,pointcut是写死的Pointcut.TRUE
- TruePointcut,拦截所有的切面
22. 回到第20步AbstractAutoProxyCreator#buildAdvisors()方法,DefaultAdvisorAdapterRegistry#wrap(Object adviceObject)
- 这里是advice类型的Object,强转返回
23. 回到第19步 AbstractAutoProxyCreator#createProxy(),ProxyFactory#getProxy(@Nullable ClassLoader classLoader)
- 创建代理,根据目标对象是否有接口来判断采用什么代理方式,cglib代理还是jdk动态代理
- 每个代理对象都是新的,与被代理对象一一对应
24. JdkDynamicAopProxy#getProxy(@Nullable ClassLoader classLoader)
- 得到代理对象
- 这个类肯定实现的InvocationHandler接口
25. JdkDynamicAopProxy#invoke(Object proxy, Method method, Object[] args)
- 一定会有invoke()方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
// 1.从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 2.被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
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...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 3.exposeProxy属性默认是false,如果你设置为true,代理对象就会被设置到ThreadLocal中
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 4.这个target就是被代理实例
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
// 5.从代理工厂中拿过滤器链 Object是一个MethodInterceptor类型的对象,其实就是一个advice对象
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.
// 6.如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 7.如果有执行链,就链式调用
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);
}
}
}
26. AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass)
- 方法有缓存,如果缓存没有传进来的那个方法走getInterceptorsAndDynamicInterceptionAdvice()
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
//获取过滤器链
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
27. DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass)
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 1.从代理工厂中获得该被代理类的所有切面advisor,config就是代理工厂对象ProxyFactory(可以看下面的断点结果)
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
//大部分走这里
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 2.如果切面的pointCut和被代理对象是匹配的,说明是切面要拦截的对象
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
// 3.接下来判断方法是否是切面pointcut需要拦截的方法
match = mm.matches(method, actualClass);
}
// 如果类和方法都匹配
if (match) {
// 4.获取到切面advisor中的advice,并且包装成MethodInterceptor类型的对象放到list中并返回
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//如果是引介切面
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 5. 里面包含所有符合条件的advice增强
return interceptorList;
}
28. DefaultAdvisorAdapterRegistry#getInterceptors(Advisor advisor)
- 获取到切面advisor中的advice,并且包装成MethodInterceptor类型的对象
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor类型的,如:AspectJAroundAdvice
//AspectJAfterAdvice
//AspectJAfterThrowingAdvice
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//处理 AspectJMethodBeforeAdvice AspectJAfterReturningAdvice
//因为这两个不是MethodInterceptor类型的advice,所以这里就把他俩包装成MethodInterceptor类型的advice
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
- 把MethodBeforeAdviceAdapter和AfterReturningAdviceAdapter放入adapters集合中
- 包装成MethodInterceptor类型的对象返回
- AfterReturningAdviceInterceptor实现了MethodInterceptor接口,并持有AfterReturningAdvice对象的引用
29. 回到第25步 JdkDynamicAopProxy#invoke(),ReflectiveMethodInvocation#ReflectiveMethodInvocation()
- 通过构造函数把得到所有advice增强方法放入interceptorsAndDynamicMethodMatchers集合,也就是执行链
30. ReflectiveMethodInvocation#proceed()
- 链式调用,功能增强的具体实现
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 1.如果执行链中的advice全部执行完,则直接调用joinPoint方法,就是被代理方法
//currentInterceptorIndex默认是-1,没执行一次就+1,直到把所有增强方法都执行完,下面的两个值就相等了
//如果相等,则执行被代理对象的被代理方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 2.反射调用被代理方法
return invokeJoinpoint();
}
// 3.在集合中按顺序(第0个,1个,2个...)执行advice的增强方法(例如around,before,after这些具体方法)
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 {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 4.调用MethodInterceptor中的invoke方法
// 这里就体现出把所有的advice都包装成MethodInterceptor对象的好处,即不需要写大量的if,else去判断advice的类型
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
31. AspectJAroundAdvice#invoke(MethodInvocation mi)
- 比如这里是around方法的增强方法,点进AspectJAroundAdvice类的invoke()方法
- AbstractAspectJAdvice#invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,@Nullable Object returnValue, @Nullable Throwable t)
- invokeAdviceMethodWithGivenArgs(Object[] args)
- jdk方法的反射调用
- 一定会走到增强的具体方法,又会走到proceed()方法
- MethodInvocationProceedingJoinPoint#proceed()
- ReflectiveMethodInvocation#proceed(),回到第30步链式调用最开始的地方
32. AspectJAroundAdvice#invoke(MethodInvocation mi)
- 再比如这里是before方法的增强方法,点进MethodBeforeAdviceInterceptor类的invoke()方法
- 先执行具体增强方法,AspectJMethodBeforeAdvice#before(Method method, Object[] args, @Nullable Object target)
- AbstractAspectJAdvice#invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)
- AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgs(Object[] args)
- jdk方法反射调用
- 回到第32步一开始,具体增强方法执行完,执行proceed()方法
- 又回到了第30步链式调用最开始的地方
添加一个全局AOP
1. 创建一个实现MethodInterceptor接口的类
- 添加全局拦截方法
package org.example.aspectJ;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;
@Component
public class WholeMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("我是全局拦截AOP,拦截了" + invocation.getMethod().getName() + "方法");
return invocation.proceed();
}
}
2. 创建一个配置类
- 用于把入口类AnnotationAwareAspectJAutoProxyCreator注册到spring容器中,对应的beanName必须是AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME(这个在上一篇文章中https://blog.csdn.net/qq_40977118/article/details/108937745介绍过了),把拦截类的beanName设置到InterceptorNames中
package org.example.aspectJ;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@Configuration
public class TargetSourceCreatorBean {
// beanDefinition中的factoryMethod属性实现的
@Bean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME)
public AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator() {
AnnotationAwareAspectJAutoProxyCreator creator = new AnnotationAwareAspectJAutoProxyCreator();
creator.setInterceptorNames("wholeMethodInterceptor");
return creator;
}
}
3. 测试方法
- 这里的userService对象是一个代理对象,所以可以拦截
- 这里想要全局拦截,一定要在bean生成代理前,把这个拦截类添加到InterceptorNames中
- 源码中是先遍历InterceptorNames中的beanName之后,才生成的代理,如果代理已经生成,你再去向InterceptorNames中添加beanName就不起作用了
4. 情况一
- 注释掉@Configuration
- 全局拦截方法没有走
- 这里是因为在执行bean.setInterceptorNames(“wholeMethodInterceptor”)之前,UserService已经被spring实例化,而且代理对象已经被创建完了
解决方法:
- 添加@Lazy
- 全局拦截方法被执行了,因为是懒加载,在手动调用applicationContext.getBean(UserService.class)方法之后,UserService才会被实例化,这时InterceptorNames中已经添加了wholeMethodInterceptor的beanName,所以在UserService生成代理之前,会添加这个TruePointcut
5. 情况二
- getBean先执行,同样是因为UserService在遍历InterceptorNames前先生成了代理对象,所以全局拦截方法没有执行
总结
initializeBean
1、检查当前的bean是否有advice
- 找到合格的切面,把工程中所有有@Aspect的类封装成Advisor返回,包含pointCut和advice
- 判断这些切面是否作用在当前bean的类上面,就是一个匹配过程
2、如果有就创建当前bean的代理
- 创建代理工厂,默认使用jdk动态代理
- 把advisors(切面)和targetSource(被代理对象)赋值给代理工厂对象
- 通过代理工厂获取代理实例,每个代理对象都是新的,被new出来的,而且实现了InvocationHandler接口
- 在代理实例的invoke方法中,从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
- 被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
- 从代理工厂中拿到被代理对象的所有切面advisor,获取到匹配的advice,并且包装成MethodInterceptor类型的对象放到list中并返回,进行链式调用invocation.proceed()
- 执行advice的增强方法,调用MethodInterceptor中的invoke方法,会走到增强的具体方法,如果是around类型的增强方法又会走到point.proceed()方法,和invocation.proceed()调用的是同一个类ReflectiveMethodInvocation中的方法,形成链式调用
- 每次执行会对次数进行加1,直到等于执行链中方法数量-1(执行次数初始值是-1),执行链中的advice全部执行完,则直接调用被代理方法,为getBean方法返回一个代理对象