前文我们介绍了关于如何学习 Spring 的源码以及解析了 spring 中加载配置文件注册 Beandefinition 的过程. 今天我们继续学习 DI 的过程.
创建实例和 DI 过程
IoC 和 DI 都是对 spring 容器特性的描述. IoC 指的是将实例的生命周期交给第三方管理 (spring). 而 DI 的侧重点在于某一个类依赖了其他的实例, 将实例注入到依赖它的实例的过程. 所以可以很明显的看出来 DI 是发生在类实例已经实例化完成之后的.
创建实例
BeanDefinition
BeanDefinition 是对 bean 属性的定义, 包含了 bean 的状态的属性, 如 bean 的 Class 对象, 单例还是原型等.
上图中是 BeanDefinition 定义的方法, 可以看出其中包括创建 Bean 的工厂类名称和 bean 的状态单例, 懒加载等.
其中大多数方法都很容易理解, 有几个属性这里需要解释下.
dependsOn
dependsOn 是指当前 Beandefinition 所表示的 Bean 依赖了其他那些 bean(不包括基本数据类型), 这里依赖的 bean 并不需要在当前 Bean 中声明, 所以不能通过依赖注入完成, 而是需要显示的定义.
autowireCandidate
autowireCandidate 用来表示当前 bean 是否可以被注入到其他实例中.
上面的内容都可以通过 xml 配置或者注解来配置.
- xml
- <bean scope="singleton" autowire-candidate="true" init-method=""factory-method="" lazy-init="true">
- </bean>
注解
- public class JavaBean {
- public void init(){
- //init
- }
- public void destroy(){
- //destroy
- }
- @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
- @Bean(initMethod = "init", destroyMethod = "destroy")
- public JavaBean getEntity(){
- return new JavaBean();
- }
- }
继承体系
在上图中实际实际被用来实现 Beandefinition 的类是 RootBeanDefinition,ChildBeanDefinition,GenericBeanDefinition. 其中 GenericBeanDefinition 是在 spring2.5 以后才出现的, spring2.5 以后都建议使用 GenericBeanDefinition. 但是由于以前的代码都是使用 RootBeanDefinition 和 ChildBeanDefinition, 所以我们也还能看到 RootBeanDefinition,ChildBeanDefinition 这些类.
大体流程
同 IoC 一样在阅读源码前先来看看一 DI 的大体流程.
refresh()
在阅读 IoC 相关实现的时候, 除开构造函数外 refresh() 就是我们最初的入口, 当时只是看了其中的部分代码. 实际上 refresh() 贯穿了 spring 启动的整个阶段. 当 refresh() 方法执行完成时基本就代表 spring 正常启动了. 在 DI 篇我们来继续看 refresh() 的其他的一些代码.
- public void refresh() throws BeansException, IllegalStateException {
- synchronized (this.startupShutdownMonitor) {
- // 读取配置文件 注册 Beandefinition
- prepareRefresh();
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- prepareBeanFactory(beanFactory);
- try {
- postProcessBeanFactory(beanFactory);
- invokeBeanFactoryPostProcessors(beanFactory);
- registerBeanPostProcessors(beanFactory);
- initMessageSource();
- initApplicationEventMulticaster();
- onRefresh();
- registerListeners();
- finishBeanFactoryInitialization(beanFactory);
- finishRefresh();
- }catch (BeansException ex) {
- logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
- destroyBeans();
- cancelRefresh(ex);
- throw ex;
- }
- }
- }
BeanFactoryPostProcessor 和 BeanPostProcessor
在进行 bean 的实例化之前会先执行 BeanFactoryPostProcessor 和注册 BeanPostProcessor.
- BeanFactoryPostProcessor
- public interface BeanFactoryPostProcessor {
- void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
- }
BeanFactoryPostProcessor 可以对 BeanDefinition 进行处理. BeanFactoryPostProcessor 在容器实际实例化任何其它的 bean 之前读取 bean 的元数据, 并且可以对其进行修改修改. 用于在执行实例化 bean 之前进行调用.
- BeanPostProcessor
- public interface BeanPostProcessor {
- Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
- Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
- }
- ```
实现 BeanPostProcessor 接口可以在 Bean 初始化的前后做一些自定义的操作, 但是不能够直接操作 BeanDefinition 元数据.
BeanFactoryPostProcessor 和 BeanPostProcessor 都是 spring 留给我们进行扩展的类. 通过实现这两个接口我们可以在 bean 的实例化过程中添加一些自定义的操作. 而需要注意的是这两个接口虽然都提供了扩展 bean 实例化的功能, 但两者确实完全不同的:
BeanFactoryPostProcessor
是在所有的 bean 都未开始实例化前调用, 其可以拿到容器中所有的 Beandefinition, 所以可以在 bean 实例化前直接修改 bean 定义的元数据.
BeanPostProcessor 里的实例化前后指的是调用 init(init-method) 方法前后, 这时实际上 bean 已经开始了实例化 (详细的可以参考类的实例化全过程), 这时取到的仅仅是某一指定类的实例. 即使进行修改也只是修改当前这一实例, 而无法对 bean 的元数据修改.
由于 postProcessor 可能会在 bean 的实例化之前进行调用, 所以在实例化前 context 肯定需要先拿到 postProcessor, 这也就可以解释上面的代码中在解析完配置文件后就开始注册 BeanFactoryPostProcessor 和 BeanPostProcessor.
listener
//tood
具体的关于 postProcessor 和 Listener 相关会在将整体流程理顺后再详细介绍.
- finishBeanFactoryInitialization(ConfigurableListableBeanFactory)
- protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
- if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
- beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
- beanFactory.setConversionService(
- beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
- }
- String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
- for (String weaverAwareName : weaverAwareNames) {
- getBean(weaverAwareName);
- }
- beanFactory.setTempClassLoader(null);
- // 缓存 bean 定义
- beanFactory.freezeConfiguration();
- beanFactory.preInstantiateSingletons();
- }
方法首先查找是否开启了注册 conversionService,conversionService 是用于进行两个类转换的, 例如之前说过了 Environment 类就依赖该实例将定义的变量转换为相应的类型.
如果要开启注册 conversionService, 可以在配置文件中配置.
接下来的代码是从 bean 定义中获取 LoadTimeWeaverAware 类型优先进行实例化. LoadTimeWeaverAware 作用是当类被加载进 jvm 是动态的转换类. 之所以优先实例化这些类是因为在实例化其他类时可能会使用到这些类, 比如 jpa 就极度依赖这些功能.
- ### preInstantiateSingletons()
- public void preInstantiateSingletons() throws BeansException {
- List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
- for (String beanName : beanNames) {
- // 获取 bean 定义
- RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- // 抽象类无法实例化
- // 非单例和懒加载在需要时才实例化
- if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
- if (isFactoryBean(beanName)) {
- // 获取 factoryBean 的实例
- final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
- boolean isEagerInit;
- if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
- isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- return ((SmartFactoryBean<?>) factory).isEagerInit();
- }
- }, getAccessControlContext());
- }else {
- isEagerInit = (factory instanceof SmartFactoryBean &&
- ((SmartFactoryBean<?>) factory).isEagerInit());
- }
- if (isEagerInit) {
- getBean(beanName);
- }
- }else {
- getBean(beanName);
- }
- }
- }
- // 实现了 SmartInitializingSingleton 接口的回调方法
- // SmartInitializingSingleton 接口同 InitializingBean 接口类似都是用于在创建 bean 时进行一些后置的操作
- // 不同之处在于 InitializingBean 是在每一个实例化的过程中进行调用 而 SmartInitializingSingleton 是在所有的单例 bean 被实例化后再 refresh 中进行回调
- for (String beanName : beanNames) {
- Object singletonInstance = getSingleton(beanName);
- if (singletonInstance instanceof SmartInitializingSingleton) {
- final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- smartSingleton.afterSingletonsInstantiated();
- return null;
- }
- }, getAccessControlContext());
- }else {
- smartSingleton.afterSingletonsInstantiated();
- }
- }
- }
- }
- ```
preInstantiateSingletons 通过一个 for 循环来实例化所有注册到容器中的 bean 定义所代表的的 bean.
在确定好每一个 beanName 所代表的的 bean 确实需要实例化后首先检查当前 beanName 是否实现了接口
而由于 ```FactoryBean``` 本身首先是一个 bean, 所以我们也可以在 ioc 容器中获取该 bean 的实例. 如果我们通过 getBean(beanName) 方法获取的实际上是 ```FactoryBean``` 产生的实例类型, 想要获取 ```FactoryBean``` 的实例需要使用 ```getBean("&" + beanName)```.
#### getBean(String)
getBean 是一个重载方法, 主要还是调用 doGetBean() 方法实现功能.
- protected <T> T doGetBean(
- final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
- throws BeansException {
- // 取该 beanName 在容器中保存的 name
- // 比如上面介绍的 factoryBean 会加一个 & 以及给 bean 配置的别名等
- final String beanName = transformedBeanName(name);
- Object bean;
- // 尝试从保存 bean 的容器中取, 如果已经存在则不用再次实例化
- Object sharedInstance = getSingleton(beanName);
- if (sharedInstance != null && args == null) {
- if (logger.isDebugEnabled()) {
- if (isSingletonCurrentlyInCreation(beanName)) {
- logger.debug("Returning eagerly cached instance of singleton bean'" + beanName +
- "'that is not fully initialized yet - a consequence of a circular reference");
- }else {
- logger.debug("Returning cached instance of singleton bean'" + beanName + "'");
- }
- }
- bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
- }else {
- // 对于非单例 bean 如果该 bean 正在被创建而又尝试再次创建则会直接抛出异常
- if (isPrototypeCurrentlyInCreation(beanName)) {
- throw new BeanCurrentlyInCreationException(beanName);
- }
- BeanFactory parentBeanFactory = getParentBeanFactory();
- if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
- //!containsBeanDefinition(beanName) 表示从当前容器中没有找到匹配的 BeanDefinition 尝试从父容器中查找
- String nameToLookup = originalBeanName(name);
- if (args != null) {
- return (T) parentBeanFactory.getBean(nameToLookup, args);
- }else {
- return parentBeanFactory.getBean(nameToLookup, requiredType);
- }
- }
- if (!typeCheckOnly) {
- // 标记当前 beanName 所表示的 bean 正在被创建或已经被创建
- markBeanAsCreated(beanName);
- }
- try {
- final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
- // 这一步根据其实现貌似主要是检查当前 BeanDefinition 表示的 bean 是否是一个抽象类, 但是前面已经检查过了 这里再次检查貌似意义不大
- checkMergedBeanDefinition(mbd, beanName, args);
- // 检查是否配置了 bean 的依赖 如果存在则需要先实例化被依赖的 bean
- String[] dependsOn = mbd.getDependsOn();
- if (dependsOn != null) {
- for (String dependsOnBean : dependsOn) {
- if (isDependent(beanName, dependsOnBean)) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Circular depends-on relationship between'" + beanName + "'and'" + dependsOnBean + "'");
- }
- registerDependentBean(dependsOnBean, beanName);
- getBean(dependsOnBean);
- }
- }
- if (mbd.isSingleton()) {
- sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
- @Override
- public Object getObject() throws BeansException {
- try {
- return createBean(beanName, mbd, args);
- }
- catch (BeansException ex) {
- destroySingleton(beanName);
- throw ex;
- }
- }
- });
- bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
- }else if (mbd.isPrototype()) {
- Object prototypeInstance = null;
- try {
- beforePrototypeCreation(beanName);
- prototypeInstance = createBean(beanName, mbd, args);
- }
- finally {
- afterPrototypeCreation(beanName);
- }
- bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
- }else {
- String scopeName = mbd.getScope();
- final Scope scope = this.scopes.get(scopeName);
- if (scope == null) {
- throw new IllegalStateException("No Scope registered for scope'" + scopeName + "'");
- }
- try {
- Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
- @Override
- public Object getObject() throws BeansException {
- beforePrototypeCreation(beanName);
- try {
- return createBean(beanName, mbd, args);
- }
- finally {
- afterPrototypeCreation(beanName);
- }
- }
- });
- bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
- }catch (IllegalStateException ex) {
- throw new BeanCreationException(beanName,
- "Scope'" + scopeName + "'is not active for the current thread;" +
- "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
- ex);
- }
- }
- }catch (BeansException ex) {
- cleanupAfterBeanCreationFailure(beanName);
- throw ex;
- }
- }
- if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
- try {
- return getTypeConverter().convertIfNecessary(bean, requiredType);
- }catch (TypeMismatchException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Failed to convert bean'" + name + "'to required type [" +
- ClassUtils.getQualifiedName(requiredType) + "]", ex);
- }
- throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
- }
- }
- return (T) bean;
- }
方法中的 try-catch 块用于创建 bean 实例, 代码很多, 不过只是根据 bean 的作用范围来进行创建如 Singleton,prototype 或者 session 等. 创建 bean 的过程大同小异, 区别仅在与实例保存的地方. 单例 bean 被保存在一个 map 中, 整个程序运行期间有效. 原型 bean 保存在另外的容器中, 每一次使用时需要重新创建.
以单例 bean 创建过程为例, 主要实现过程都在 ```getSingleton(...)``` 方法中了.```getSingleton(...)``` 的主要功能就是检查 bean 是否已经创建, 如果没创建就进行创建然后保存到容器中. 创建 bean 的过程由一个匿名内部类实现.
- #### createBean(String beanName, RootBeanDefinition mbd, Object[] args)
- protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
- throws BeanCreationException {
- resolveBeanClass(mbd, beanName);
- try {
- mbd.prepareMethodOverrides();
- }catch (BeanDefinitionValidationException ex) {
- throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
- beanName, "Validation of method overrides failed", ex);
- }
- try {
- // 首先尝试执行 BeanPostProcessor, 如果存在后置处理器 那么首先实例化 bean 执行处理器
- Object bean = resolveBeforeInstantiation(beanName, mbd);
- if (bean != null) {
- return bean;
- }
- }catch (Throwable ex) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "BeanPostProcessor before instantiation of bean failed", ex);
- }
- // 不存在后置处理器或者存在的执行处理器过程创建实例失败或没有创建实例的动作则执行下面的方法
- Object beanInstance = doCreateBean(beanName, mbd, args);
- if (logger.isDebugEnabled()) {
- logger.debug("Finished creating instance of bean'" + beanName + "'");
- }
- return beanInstance;
- }
上面方法中有这样一句 ```mbd.prepareMethodOverrides()```.```methodOverrides``` 实际上市 BeanDefinition 中的一个属性. 其主要用于记录在配置文件中 lookup-method 和 replaced-method 参数设置的值. 详情可以看这里:[methodOverrides](https://blog.csdn.net/G0_hw/article/details/82149000)
- #### doCreateBean(...)
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
- BeanWrapper instanceWrapper = null;
- if (mbd.isSingleton()) {
- // 如果已经实例化需要重新实例化则从缓存中删除 重新设置
- instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
- }
- if (instanceWrapper == null) {
- instanceWrapper = createBeanInstance(beanName, mbd, args);
- }
- //more code
- }
方法开头显示创建了一个 BeanWrapper 的对象, BeanWrapper 相当于一个代理器, Spring 委托 BeanWrapper 来完成 bean 内部属性的初始化.
上述方法代码很多, 在创建阶段只需要关注前几行. 如果该 bean 的实例未被创建则直接创建一个. 创建的方法有 createBeanInstance 完成.
- #### createBeanInstance(...)
- protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
- Class<?> beanClass = resolveBeanClass(mbd, beanName);
- // 判断当前 bean 类是否被定义为 public 非 public 的类无法在其他类中实例化
- if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
- }
- if (mbd.getFactoryMethodName() != null) {
- return instantiateUsingFactoryMethod(beanName, mbd, args);
- }
- boolean resolved = false;
- boolean autowireNecessary = false;
- if (args == null) {
- synchronized (mbd.constructorArgumentLock) {
- if (mbd.resolvedConstructorOrFactoryMethod != null) {
- resolved = true;
- autowireNecessary = mbd.constructorArgumentsResolved;
- }
- }
- }
- if (resolved) {
- if (autowireNecessary) {
- return autowireConstructor(beanName, mbd, null, null);
- }
- else {
- return instantiateBean(beanName, mbd);
- }
- }
- Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
- if (ctors != null ||
- mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
- mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
- return autowireConstructor(beanName, mbd, ctors, args);
- }
- return instantiateBean(beanName, mbd);
- }
该方法先是尝试查看是否配置了工厂方法, 如果存在工厂方法则由工厂方法进行创建.
接下来的几行代码是用来提升性能的. spring 在创建实例后会将创建该实例的 constructor 方法缓存, 这样下一次需要创建该 bean 时直接取出构造方法创建即可不需要再重新解析一次.
如果没有工厂方法并且构造方法也没有缓存, 同时没有找到有参的构造函数, 那么会通过放射调用类的默认无参构造函数.
#### instantiateBean(String, RootBeanDefinition)
该实例化方法没有太多解析的必要, 基本就是通过反射的原理获取无参构造函数, 通过构造函数来实例化类.
### DI
到这里为止创建一个实例的过程就完成了, 接下来就是检查该实例是否需要被注入其他的属性了.
#### 回到 doCreateBean(...)
前面在创建 bean 实例时调用到了 doCreateBean(...) 方法, 在创建好实例后的后续功能也依赖于该方法.
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
- // other-code
- Object exposedObject = bean;
- try {
- populateBean(beanName, mbd, instanceWrapper);
- if (exposedObject != null) {
- exposedObject = initializeBean(beanName, exposedObject, mbd);
- }
- } catch (Throwable ex) {
- if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
- throw (BeanCreationException) ex;
- }else {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
- }
- }
- // other-code
- return exposedObject;
- }
在 DI 阶段我们需要关注的就上上面的代码, 首先是通过 populateBean 方法对在配置文件中配置的 property 属性进行设置值.
populateBean 顾名思义就是对 bean 中的属性添加数据. populateBean 中其实是通过后置处理器来进行属性的设置, 主要的代码如下:
- PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
- if (hasInstAwareBpps) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
- if (pvs == null) {
- return;
- }
- }
- }
- }
spring 中默认注册了以下几种 beanPostProcessor, 如下:
![beanPostProcessor](https://user-gold-cdn.xitu.io/2019/6/22/16b7cfcd1669ee2a?w=695&h=426&f=png&s=32220)
每一个 beanPostProcessor 都会在实例化前后相应的地方进行调用. 在这里我们需要关注的是 ```AutowiredAnnotationBeanPostProcessor```,```RequiredAnnotationBeanPostProcessor```,```CommonAnnotationBeanPostProcessor``` 这几个注解.
顾名思义这几个 beanPostProcessor 都是用来处理注解的, 对应用来处理 ```@Autowired```,```@Required```,```@Common``` 几个注解.
这里以 ```@Autowored``` 的处理为例.
- #### AutowiredAnnotationBeanPostProcessor
- public PropertyValues postProcessPropertyValues(
- PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
- InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
- try {
- metadata.inject(bean, beanName, pvs);
- }catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
- }
- return pvs;
- }
- private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
- LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
- Class<?> targetClass = clazz;
- do {
- LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
- for (Field field : targetClass.getDeclaredFields()) {
- AnnotationAttributes annotation = findAutowiredAnnotation(field);
- if (annotation != null) {
- if (Modifier.isStatic(field.getModifiers())) {
- if (logger.isWarnEnabled()) {
- logger.warn("Autowired annotation is not supported on static fields:" + field);
- }
- continue;
- }
- boolean required = determineRequiredStatus(annotation);
- currElements.add(new AutowiredFieldElement(field, required));
- }
- }
- for (Method method : targetClass.getDeclaredMethods()) {
- Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
- if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
- continue;
- }
- AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
- if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
- if (Modifier.isStatic(method.getModifiers())) {
- if (logger.isWarnEnabled()) {
- logger.warn("Autowired annotation is not supported on static methods:" + method);
- }
- continue;
- }
- if (method.getParameterTypes().length == 0) {
- if (logger.isWarnEnabled()) {
- logger.warn("Autowired annotation should be used on methods with actual parameters:" + method);
- }
- }
- boolean required = determineRequiredStatus(ann);
- PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
- currElements.add(new AutowiredMethodElement(method, required, pd));
- }
- }
- elements.addAll(0, currElements);
- targetClass = targetClass.getSuperclass();
- }
- while (targetClass != null && targetClass != Object.class);
- return new InjectionMetadata(clazz, elements);
- }
该方法主要就是通过解析当前 bean 有哪些属性被 ```@Autowired``` 注解修饰, 将其封装为一个 ```InjectionMetadata``` 对象. 解析的过程通过 ```findAutowiringMetadata(String beanName, Class<?> clazz)``` 完成, 但实际上主要还是通过上面的 ```buildAutowiringMetadata(Class<?> clazz)``` 完成.
方法比较简单, 首先就是遍历 bean 的所有字段 (Field), 通过反射的方法查找字段上的注解, 如果存在匹配的注解 (```AutowiredAnnotationBeanPostProcessor``` 匹配的就是 ```@Autowired```). 如果存在该注解就将这个字段记录表示需要进行注入.
当将字段遍历完成后就取出所有的方法, 查找方法上是否有该注解, 如果存在的话同理记录下该方法.
对于被记录下的字段或者方法会被封装成一个 ```InjectedElement``` 对象. 通过该对象的 inject 方法完成注入工作.
- protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
- Field field = (Field) this.member;
- try {
- Object value;
- if (this.cached) {
- value = resolvedCachedArgument(beanName, this.cachedFieldValue);
- } else {
- DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
- desc.setContainingClass(bean.getClass());
- Set
刚方法总体来说比较简单, 首先是查询当前 bean 的依赖是否已经被缓存, 如果缓存了则从缓存中取即可.
如果是第一次解析则从 beanfactory 中获取相应的依赖属性.
synchronized 代码块主要就是将解析后的依赖的值缓存起来, 建立当前 bean 和其依赖的属性之间的关系. 当下一次创建该类型的 bean 时可以直接使用不需重新解析.
而真正的属性注入是依赖着几行代码:
- if (value != null) {
- ReflectionUtils.makeAccessible(field);
- field.set(bean, value);
- }
- ```
上面的代码没有任何的难度, 就是对 JDK 中反射的 API 的使用.
基本上后面就是重复这个过程对 bean 的属性进行注入, 在这一过程中最重要的就是 beanPostProcessor, 注入都已依赖这一组完成的.
来源: https://www.cnblogs.com/liyus/p/11067895.html