Spring DI原理

本文详细介绍了Spring中的依赖注入(DI)原理,包括依赖注入的发生时间,BeanFactory接口的角色,以及AbstractBeanFactory和AbstractAutowireCapableBeanFactory如何创建并初始化Bean,特别是依赖注入的具体实现过程。通过源码分析,揭示了Spring如何使用反射和CGLib创建Bean实例,并进行属性的setter注入。
摘要由CSDN通过智能技术生成

DI
DI(Dependency Injection)依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。 

依赖注入发生的时间当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后,IOC 容器中已经管理类 Bean定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入,依赖注入在以下两种情况发生:
1)、用户第一次调用 getBean()方法时,IOC 容器触发依赖注入。
2)、当用户在配置文件中将<bean>元素配置了 lazy-init=false 属性,即让容器在解析注册 Bean 定义时进行预实例化,触发依赖注入。  

BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和最基本的编程规范。BeanFactory 接口中定义了几个 getBean()方法,就是用户向 IOC 容器索取管理的Bean 的方法,我们通过分析其子类AbstractBeanFactory 的具体实现,理解 Spring IOC 容器在用户索取 Bean 时如何完成依赖注入。

AbstractBeanFactory 的 getBean()相关方法的源码如下:

[Java] 纯文本查看 复制代码

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

//获取IOC容器中指定名称的Bean

    @Override

    public Object getBean(String name) throws BeansException {

        //doGetBean才是真正向IoC容器获取被管理Bean的过程

        return doGetBean(name, null, null, false);

    }

 

    //获取IOC容器中指定名称和类型的Bean

    @Override

    public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {

        //doGetBean才是真正向IoC容器获取被管理Bean的过程

        return doGetBean(name, requiredType, null, false);

    }

 

    //获取IOC容器中指定名称和参数的Bean

    @Override

    public Object getBean(String name, Object... args) throws BeansException {

        //doGetBean才是真正向IoC容器获取被管理Bean的过程

        return doGetBean(name, null, args, false);

    }

 

    //获取IOC容器中指定名称、类型和参数的Bean

    public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)

            throws BeansException {

        //doGetBean才是真正向IoC容器获取被管理Bean的过程

        return doGetBean(name, requiredType, args, false);

    }

 

    @SuppressWarnings("unchecked")

    //真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,

            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

 

        //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖

        //如果指定的是别名,将别名转换为规范的Bean名称

        final String beanName = transformedBeanName(name);

        Object bean;

 

        // Eagerly check singleton cache for manually registered singletons.

        //先从缓存中取是否已经有被创建过的单态类型的Bean

        //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建

        Object sharedInstance = getSingleton(beanName);

        //IOC容器创建单例模式Bean实例对象

        if (sharedInstance != null && args == null) {

            if (logger.isDebugEnabled()) {

                //如果指定名称的Bean在容器中已有单例模式的Bean被创建

                //直接返回已经创建的Bean

                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的实例对象,主要是完成FactoryBean的相关处理

            //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是

            //创建创建对象的工厂Bean,两者之间有区别

            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

        }

 

        else {

            // Fail if we're already creating this bean instance:

            // We're assumably within a circular reference.

            //缓存没有正在创建的单例模式Bean

            //缓存中已经有已经创建的原型模式Bean

            //但是由于循环引用的问题导致实例化对象失败

            if (isPrototypeCurrentlyInCreation(beanName)) {

                throw new BeanCurrentlyInCreationException(beanName);

            }

 

            // Check if bean definition exists in this factory.

            //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否

            //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器

            //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找

            BeanFactory parentBeanFactory = getParentBeanFactory();

            //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean

            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

                // Not found -> check parent.

                //解析指定Bean名称的原始名称

                String nameToLookup = originalBeanName(name);

                if (parentBeanFactory instanceof AbstractBeanFactory) {

                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(

                            nameToLookup, requiredType, args, typeCheckOnly);

                }

                else if (args != null) {

                    // Delegation to parent with explicit args.

                    //委派父级容器根据指定名称和显式的参数查找

                    return (T) parentBeanFactory.getBean(nameToLookup, args);

                }

                else {

                    // No args -> delegate to standard getBean method.

                    //委派父级容器根据指定名称和类型查找

                    return parentBeanFactory.getBean(nameToLookup, requiredType);

                }

            }

 

            //创建的Bean是否需要进行类型验证,一般不需要

            if (!typeCheckOnly) {

                //向容器标记指定的Bean已经被创建

                markBeanAsCreated(beanName);

            }

 

            try {

                //根据指定Bean名称获取其父级的Bean定义

                //主要解决Bean继承时子类合并父类公共属性问题

                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

                checkMergedBeanDefinition(mbd, beanName, args);

 

                // Guarantee initialization of beans that the current bean depends on.

                //获取当前Bean所有依赖Bean的名称

                String[] dependsOn = mbd.getDependsOn();

                //如果当前Bean有依赖Bean

                if (dependsOn != null) {

                    for (String dep : dependsOn) {

                        if (isDependent(beanName, dep)) {

                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");

                        }

                        //递归调用getBean方法,获取当前Bean的依赖Bean

                        registerDependentBean(dep, beanName);

                        //把被依赖Bean注册给当前依赖的Bean

                        getBean(dep);

                    }

                }

 

                // Create bean instance.

                //创建单例模式Bean的实例对象

                if (mbd.isSingleton()) {

                    //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象

                    sharedInstance = getSingleton(beanName, () -> {

                        try {

                            //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义

                            return createBean(beanName, mbd, args);

                        }

                        catch (BeansException ex) {

                            // Explicitly remove instance from singleton cache: It might have been put there

                            // eagerly by the creation process, to allow for circular reference resolution.

                            // Also remove any beans that received a temporary reference to the bean.

                            //显式地从容器单例模式Bean缓存中清除实例对象

                            destroySingleton(beanName);

                            throw ex;

                        }

                    });

                    //获取给定Bean的实例对象

                    bea

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值