15. 给代理对象的属性设置值
15. 给代理对象的属性设置值
工程结构
lqf-spring-step-15
├── main
│ ├── java
│ │ └── lqf
│ │ └── springframework
│ │ ├── aop
│ │ │ ├── AdvisedSupport.java
│ │ │ ├── Advisor.java
│ │ │ ├── BeforeAdvice.java
│ │ │ ├── ClassFilter.java
│ │ │ ├── MethodBeforeAdvice.java
│ │ │ ├── MethodMatcher.java
│ │ │ ├── Pointcut.java
│ │ │ ├── PointcutAdvisor.java
│ │ │ ├── TargetSource.java
│ │ │ ├── aspectj
│ │ │ │ ├── AspectJExpressionPointcut.java
│ │ │ │ └── AspectJExpressionPointcutAdvisor.java
│ │ │ └── framework
│ │ │ ├── AopProxy.java
│ │ │ ├── Cglib2AopProxy.java
│ │ │ ├── JdkDynamicAopProxy.java
│ │ │ ├── ProxyFactory.java
│ │ │ ├── ReflectiveMethodInvocation.java
│ │ │ ├── adapter
│ │ │ │ └── MethodBeforeAdviceInterceptor.java
│ │ │ └── autoproxy
│ │ │ └── DefaultAdvisorAutoProxyCreator.java
│ │ ├── beans
│ │ │ ├── BeansException.java
│ │ │ ├── PropertyValue.java
│ │ │ ├── PropertyValues.java
│ │ │ └── factory
│ │ │ ├── Aware.java
│ │ │ ├── BeanClassLoaderAware.java
│ │ │ ├── BeanFactory.java
│ │ │ ├── BeanFactoryAware.java
│ │ │ ├── BeanNameAware.java
│ │ │ ├── ConfigurableListableBeanFactory.java
│ │ │ ├── DisposableBean.java
│ │ │ ├── FactoryBean.java
│ │ │ ├── HierarchicalBeanFactory.java
│ │ │ ├── InitializingBean.java
│ │ │ ├── ListableBeanFactory.java
│ │ │ ├── PropertyPlaceholderConfigurer.java
│ │ │ ├── annotation
│ │ │ │ ├── Autowired.java
│ │ │ │ ├── AutowiredAnnotationBeanPostProcessor.java
│ │ │ │ ├── Qualifier.java
│ │ │ │ └── Value.java
│ │ │ ├── config
│ │ │ │ ├── AutowireCapableBeanFactory.java
│ │ │ │ ├── BeanDefinition.java
│ │ │ │ ├── BeanFactoryPostProcessor.java
│ │ │ │ ├── BeanPostProcessor.java
│ │ │ │ ├── BeanReference.java
│ │ │ │ ├── ConfigurableBeanFactory.java
│ │ │ │ ├── InstantiationAwareBeanPostProcessor.java
│ │ │ │ └── SingletonBeanRegistry.java
│ │ │ ├── support
│ │ │ │ ├── AbstractAutowireCapableBeanFactory.java
│ │ │ │ ├── AbstractBeanDefinitionReader.java
│ │ │ │ ├── AbstractBeanFactory.java
│ │ │ │ ├── BeanDefinitionReader.java
│ │ │ │ ├── BeanDefinitionRegistry.java
│ │ │ │ ├── CglibSubclassingInstantiationStrategy.java
│ │ │ │ ├── DefaultListableBeanFactory.java
│ │ │ │ ├── DefaultSingletonBeanRegistry.java
│ │ │ │ ├── DisposableBeanAdapter.java
│ │ │ │ ├── FactoryBeanRegistrySupport.java
│ │ │ │ ├── InstantiationStrategy.java
│ │ │ │ └── SimpleInstantiationStrategy.java
│ │ │ └── xml
│ │ │ └── XmlBeanDefinitionReader.java
│ │ ├── context
│ │ │ ├── ApplicationContext.java
│ │ │ ├── ApplicationContextAware.java
│ │ │ ├── ApplicationEvent.java
│ │ │ ├── ApplicationEventPublisher.java
│ │ │ ├── ApplicationListener.java
│ │ │ ├── ConfigurableApplicationContext.java
│ │ │ ├── annotation
│ │ │ │ ├── ClassPathBeanDefinitionScanner.java
│ │ │ │ ├── ClassPathScanningCandidateComponentProvider.java
│ │ │ │ └── Scope.java
│ │ │ ├── event
│ │ │ │ ├── AbstractApplicationEventMulticaster.java
│ │ │ │ ├── ApplicationContextEvent.java
│ │ │ │ ├── ApplicationEventMulticaster.java
│ │ │ │ ├── ContextClosedEvent.java
│ │ │ │ ├── ContextRefreshedEvent.java
│ │ │ │ └── SimpleApplicationEventMulticaster.java
│ │ │ └── support
│ │ │ ├── AbstractApplicationContext.java
│ │ │ ├── AbstractRefreshableApplicationContext.java
│ │ │ ├── AbstractXmlApplicationContext.java
│ │ │ ├── ApplicationContextAwareProcessor.java
│ │ │ └── ClassPathXmlApplicationContext.java
│ │ ├── core
│ │ │ └── io
│ │ │ ├── ClassPathResource.java
│ │ │ ├── DefaultResourceLoader.java
│ │ │ ├── FileSystemResource.java
│ │ │ ├── Resource.java
│ │ │ ├── ResourceLoader.java
│ │ │ └── UrlResource.java
│ │ ├── stereotype
│ │ │ └── Component.java
│ │ └── util
│ │ ├── ClassUtils.java
│ │ └── StringValueResolver.java
│ └── resources
└── test
├── java
│ └── lqf
│ └── springframework
│ ├── SpringTest.java
│ └── service
│ ├── IUserService.java
│ ├── UserDao.java
│ ├── UserService.java
│ └── UserServiceBeforeAdvice.java
└── resources
├── spring.xml
└── token.properties
在Bean的生命周期中创建代理对象的类关系,如图

- 虽然要完成的是关于代理对象中属性的填充问题,但实际解决的思路是处理在 Bean
的生命周期中合适的位置(初始化initializeBean)中处理代理类的创建。 - 主要包括:DefaultAdvisorAutoProxyCreator 类创建代理对象的操作放置在 postProcessAfterInitialization 方法中以及对应在
AbstractAutowireCapableBeanFactory 完成初始化方法的调用操作。 - 在 Spring 框架中,AbstractAutowireCapableBeanFactory 类里使用的是 CglibSubclassingInstantiationStrategy
创建对象,所以有需要判断对象获取接口的方法中,也都需要判断是否为
CGlib创建,否则是不能正确获取到接口的。如:ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;
设计
按照创建代理对象的操作 DefaultAdvisorAutoProxyCreator 实现的 InstantiationAwareBeanPostProcessor 接口,原本在 Before
中的操作,则需要放到 After 中处理。整体设计如下:

- 在创建 Bean 对象
createBean的生命周期中,有一个阶段是在 Bean 对象属性填充完成以后,执行 Bean 的初始化方法和
BeanPostProcessor 的前置和后置处理方法。 - 在 DefaultAdvisorAutoProxyCreator 用于创建代理对象的操作中,需要把创建操作从 postProcessBeforeInstantiation 方法中迁移到
postProcessAfterInitialization,这样才能满足 Bean 属性填充后的创建操作。
实现
判断CGlib对象
源码: lqf.springframework.aop.TargetSource
-
在 TargetSource#getTargetClass 是用于获取 target 对象的接口信息的,那么这个 target 可能是 JDK代理
创建也可能是CGlib创建,为了保证都能正确的获取到结果,这里需要增加判读ClassUtils.isCglibProxyClass(clazz)。
迁移创建AOP代理方法
源码: lqf.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
- 关于 DefaultAdvisorAutoProxyCreator 类的操作主要就是把创建 AOP 代理的操作从 postProcessBeforeInstantiation 移动到
postProcessAfterInitialization 中去。 - 通过设置一些 AOP 的必备参数后,返回代理对象
new ProxyFactory(advisedSupport).getProxy()这个代理对象中就包括间接调用了
TargetSource 中对 getTargetClass() 的获取。
在Bean的生命周期中初始化执行
源码: lqf.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
- 在 AbstractAutowireCapableBeanFactory#createBean 方法中,其实关注点就在于 initializeBean ->
applyBeanPostProcessorsAfterInitialization 这一块逻辑的调用,最终完成 AOP 代理对象的创建操作。
总结
-
核心知识内容主要是完善了 Bean 的生命周期,在创建类的操作中完成代理对象的创建,通过这样的方式就可以让代理对象中的属性也可以随着创建过程被填充进去。
-
除了核心功能的实现外也要关注到对象的初始化操作是
CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy,这两种方式中的 CGlib 创建对象,会影响到很多地方用于接口获取的操作,因为
CGlib 创建对象走的是 ASM 字节码生成的操作,所以和普通的 JDK 代理生成对象是不一样,需要注意。