Skip to content

Bean 的实例化之 @Autowired、@Value

├─finishBeanFactoryInitialization(beanFactory); Spring 核心方法中的
│ ├─beanFactory.preInstantiateSingletons();
│ │ ├─getBean(beanName);
│ │ │ ├─doGetBean(name, null, null, false);
│ │ │ │ ├─这里完成了对所有 MergedBeanDefinitionPostProcessor 实现类的调用。
│ │ │ │ ├─如:CommonAnnotationBeanPostProcessor(@PostConstruct、@PreDestroy、@Resource)
│ │ │ │ ├─如:AutowiredAnnotationBeanPostProcessor(@Autowired, @Value)
│ │ │ │ ├─applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
│ │ │ │ │ ├─processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor 支持了@Autowired, @Value 等注解的扫描解析工作。

  • 收集注解 @Autowired @Value
  • 完成 @Autowired 的依赖注入(因为实现了 InstantiationAwareBeanPostProcessor)。
  • 支持的注解类型可以在构造函数或者 Static 静态块中找。收集过程基本上跟 @Resource 注解的收集差不多。
  • doCreateBean 时,寻找当前正在实例化的 bean 中有 @Autowired 注解的构造函数。然后把有有 @Autowired 注解的构造函数返回。
  • 不管是 Field、Method、还是构造函数中有@Autowired 注解引入的类,都是通过 getBean 方法进行实例化获取 bean 的实例的。
java
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
        try {
            this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                    ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - simply skip.
        }
    }

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
}

自动注入 bean 到 Map 集合

java
package com.github.mengweijin.mybatisplus.demo.autowiredmap.bean;

public interface Apple {
    void execute();
}

@Slf4j
@Component(BigApple.BEAN_NAME)
public class BigApple implements Apple {
    public static final String BEAN_NAME = "bigApple";
    @Override
    public void execute() {
        log.debug("execute {}", this.getClass().getSimpleName());
    }
}

@Slf4j
@Component(SmallApple.BEAN_NAME)
public class SmallApple implements Apple {
    public static final String BEAN_NAME = "smallApple";
    @Override
    public void execute() {
        log.debug("execute {}", this.getClass().getSimpleName());
    }
}
java
package com.github.mengweijin.mybatisplus.demo.autowiredmap;

import com.github.mengweijin.mybatisplus.demo.autowiredmap.bean.Apple;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;

@Slf4j
@Service
public class AppleService {
    /**
     * Spring 会自动注入所有实现了 Apple 接口的 bean 到这个 appleBeanMap 中,其中 key 为 spring bean 的 name.
     */
    @Autowired
    private Map<String, Apple> appleMap;

    /**
     * 执行所有实现类的方法
     */
    public void executeAll() {
        appleMap.forEach((beanName, apple) -> apple.execute());
    }

    /**
     * 根据类型调用不同的实现类方法
     *
     * @param beanName
     */
    public void execute(String beanName) {
        appleMap.get(beanName).execute();
    }
}

测试

java
package com.github.mengweijin.mybatisplus.demo.autowiredmap;

import com.github.mengweijin.mybatisplus.demo.autowiredmap.bean.BigApple;
import com.github.mengweijin.mybatisplus.demo.autowiredmap.bean.SmallApple;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@Slf4j
public class AutowiredMapTest {

    @Test
    public void test() {
        String basePackages = "com.github.mengweijin.mybatisplus.demo.autowiredmap";
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(basePackages);

        AppleService bean = context.getBean(AppleService.class);

        log.debug("******************************************************");
        // 执行全部实现类
        bean.executeAll();
        log.debug("******************************************************");

        // 根据类型调用不同的实现类方法
        bean.execute(BigApple.BEAN_NAME);
        bean.execute(SmallApple.BEAN_NAME);
        log.debug("******************************************************");

        context.close();
    }
}