Spring 依赖注入原理
Spring 面试 About 9,307 words版本
spring-context 5.2.6.RELEASE
依赖注入
AutowiredAnnotationBeanPostProcessor
处理@Autowired
、@Value
注解。
CommonAnnotationBeanPostProcessor
处理@Resource
。
案例
@Service
public class TestService {
@Autowired
private TestDao testDao;
@Value("TestValue")
private String testValue;
@Resource
private ResourceBean resourceBean;
public TestService() {
System.out.println("TestService construct");
}
}
@Repository
public class TestDao {
public TestDao() {
System.out.println("TestDao construct");
}
}
@Component
public class ResourceBean {
public ResourceBean() {
System.out.println("ResourceBean construct");
}
}
原理
实例化单例bean
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
}
doCreateBean
方法中进行createBeanInstance
实例化,和populateBean
中给成员变量赋值。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 使用反射创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// Initialize the bean instance.
Object exposedObject = bean;
// 填充实例中的属性
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
return exposedObject;
}
}
populateBean
方法中对BeanPostProcessor
所有后置处理器进行遍历,postProcessProperties
处理成员变量的赋值。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对实现了 InstantiationAwareBeanPostProcessor 接口的后置处理器进行成员变量处理
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
pvs = pvsToUse;
}
}
}
}
AutowiredAnnotationBeanPostProcessor
处理@Autowired
、@Value
注解。
抽象类InstantiationAwareBeanPostProcessorAdapter
实现了SmartInstantiationAwareBeanPostProcessor
接口,而接口SmartInstantiationAwareBeanPostProcessor
继承自InstantiationAwareBeanPostProcessor
。
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 注入成员变量属性
metadata.inject(bean, beanName, pvs);
return pvs;
}
}
CommonAnnotationBeanPostProcessor
处理@Resource
// org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
// 注入成员变量属性
metadata.inject(bean, beanName, pvs);
return pvs;
}
}
InjectedElement
的inject
注入
// org.springframework.beans.factory.annotation.InjectionMetadata#inject
public class InjectionMetadata {
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
}
@Autowired
、@Value
注入流程走AutowiredFieldElement
复写的inject
方法。
field.set(bean, value);
就是对成员变量赋值
// org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 解析注入的 @Autowired 依赖,如果没有实例化和填充属性,则先进行依赖的实例化和填充属性
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
if (value != null) {
// 将 private 的属性设置为可以被反射访问
ReflectionUtils.makeAccessible(field);
// 对字段赋值
field.set(bean, value);
}
}
}
@Resource
注入流程走InjectionMetadata
中抽象类InjectedElement
的inject
方法。
field.set(target, getResourceToInject(target, requestingBeanName));
:对成员变量赋值
// org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject
public class InjectionMetadata {
// @Resource 走的此处的 inject
public abstract static class InjectedElement {
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
// 对成员变量赋值
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
}
完整调用栈
inject:670, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation)
inject:130, InjectionMetadata (org.springframework.beans.factory.annotation)
postProcessProperties:399, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
populateBean:1422, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1268650975 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$32)
getSingleton:226, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:895, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:878, AbstractApplicationContext (org.springframework.context.support)
refresh:550, AbstractApplicationContext (org.springframework.context.support)
<init>:89, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:13, Test6 (com.example.learn)
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓