首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring Bean 详解

Spring Bean 详解

作者头像
用户7630333
发布于 2023-12-07 11:01:48
发布于 2023-12-07 11:01:48
28200
代码可运行
举报
文章被收录于专栏:look Javalook Java
运行总次数:0
代码可运行

Spring Bean 详解

Ioc实例化Bean的三种方式

1 创建Bean

1 使用无参构造函数

这也是我们常用的一种。在默认情况下,它会通过反射调⽤⽆参构造函数来创建对象。如果类中没有⽆参构造函数,将创建 失败。

  • class: 为需要注册Bean类文件的位置

applicationContext.xml配置文件

测试类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author : look-word
 * 2022-08-25 11:36
 **/
public class IocTest {
    @Test
    public void testIoc() {
        ApplicationContext context = // 读取配置文件
                new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        // 容器中根据名称获取Bean
        ConnectionUtils connectionUtils
                = (ConnectionUtils) context.getBean("connectionUtils");
        System.out.println(connectionUtils);
    }
}

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 输出了对象的地址
com.lagou.edu.utils.ConnectionUtils@3ecd23d9

2 使用静态方法创建

  • 简单来说,就是调用某个类的静态方法创建对象

在实际开发中,我们使⽤的对象有些时候并不是直接通过构造函数就可以创建出来的,它可能在创 建的过程 中会做很多额外的操作。此时会提供⼀个创建对象的⽅法,恰好这个⽅法是static修饰的 ⽅法,即是此种情况: 例如,我们在做Jdbc操作时,会⽤到java.sql.Connection接⼝的实现类,如果是mysql数据库,那 么⽤的就 是JDBC4Connection,但是我们不会去写 JDBC4Connection connection = new JDBC4Connection() ,因为我们要注册驱动,还要提供URL和凭证信息, ⽤ DriverManager.getConnection ⽅法来获取连接。那么在实际开发中,尤其早期的项⽬没有使⽤Spring框架来管理对象的创建,但是在设计时使⽤了 ⼯⼚模式 解耦,那么当接⼊spring之后,⼯⼚类创建对象就具有和上述例⼦相同特征,即可采⽤ 此种⽅式配置。

CreateBeanFactory

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author : look-word
 * 2022-08-25 15:50
 **/
public class CreateBeanFactory {
    /**
     * 使⽤静态⽅法创建对象的配置⽅式
     */
    public static ConnectionUtils getInstanceStatic(){
        return new ConnectionUtils();
    }
}

applicationContext.xml配置文件


3 使⽤实例化调用成员⽅法创建

  • 简单来说,就是创建一个类,然后再通过这个类的某个方法创建我们需要的对象。(不推荐,需要创建额外对象)

CreateBeanFactory:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 使⽤成员⽅法创建对象的配置⽅式
     */
    public  ConnectionUtils getInstance(){
        return new ConnectionUtils();
    }

applicationContext.xml配置文件


2 lazy—init 延迟加载

配置方式

xml配置延迟加载:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <!--
        lazy-init:延迟加载,true代表延迟,false代表立即加载,默认是false 
    -->
    <bean id="lazyResult" class="com.lagou.edu.pojo.Result" lazy-init="true"/>
注解配值延迟加载:

可以配置到许多地方,如类似,方法上等等

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Lazy
@Component
public class XXXX {
    ...
}

加载原理

当使用上述三种配置后,Spring在扫描加载Bean时会读取@Lazy和@Component注解相应值,并设置Bean定义的lazyInit属性。读取注解配置时最终会调用ClassPathBeanDefinitionScanner及其子类实现的doScan方法,在这个方法中完成注解的读取配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClassPathBeanDefinitionScanner 
        extends ClassPathScanningCandidateComponentProvider {
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
       // 不管是读取注解或者XML配置方式bean,最终读取加载Bean时都会进入到该方法
       // 对相应的包进行处理
       // beanDefinitions是保存返回bean定义的集合
       Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
       // 遍历多个包下的类
       for (String basePackage : basePackages) {
          // 获取满足条件的bean定义集合
          Set<BeanDefinition> candidates = 
                  findCandidateComponents(basePackage);
          // 对每个bean定义进行处理
          for (BeanDefinition candidate : candidates) {
             ScopeMetadata scopeMetadata = this.scopeMetadataResolver
                     .resolveScopeMetadata(candidate);
             candidate.setScope(scopeMetadata.getScopeName());
             String beanName = this.beanNameGenerator
                     .generateBeanName(candidate, this.registry);
             // 这个方法会处理@ComponentScan中的lazyInit值,因为在使用
             // @ComponentScan注解时会首先把该值赋值到beanDefinitionDefaults
             // 默认bean定义值的对象中,在postProcessBeanDefinition方法中
             // 会首先应用一次这些默认值,其中就包括lazyInit、autowireMode等
             if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition(
                        (AbstractBeanDefinition) candidate, beanName);
             }
             // 读取@Lazy、@Primary和@DependsOn等注解值
             if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils
                        .processCommonDefinitionAnnotations(
                                (AnnotatedBeanDefinition) candidate);
             }
             // 如果候选者满足要求则将其注册到Bean定义中心
             if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = 
                        new BeanDefinitionHolder(candidate, beanName);
                definitionHolder = AnnotationConfigUtils
                        .applyScopedProxyMode(scopeMetadata, 
                            definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                // 注册bean定义
                registerBeanDefinition(definitionHolder, this.registry);
             }
          }
       }
       return beanDefinitions;
    }
    protected void postProcessBeanDefinition(
            AbstractBeanDefinition beanDefinition, String beanName) {
       // 此处会应用默认值,如lazyInit、autowireMode、initMethod等
       beanDefinition.applyDefaults(this.beanDefinitionDefaults);
       if (this.autowireCandidatePatterns != null) {
          beanDefinition.setAutowireCandidate(PatternMatchUtils
                  .simpleMatch(this.autowireCandidatePatterns, beanName));
       }
    }
}

经过ClassPathBeanDefinitionScanner或子类实现的扫描读取后,延迟加载的配置便被配置到了Bean定义中,等初始化时再使用该属性,这里需要注意的是@ComponentScan延迟加载属性是可以被@Lazy覆盖的,因为@Lazy是在@ComponentScan后面处理的。

使用细节

Spring框架延迟加载属性在调用getBean之后将会失效,因为getBean方法是初始化bean的入口,这不难理解,那么平时我们使用@Autowired等自动注入注解时能和@Lazy注解一起使用吗?接下来我们从两个实例来说明一下,这两个实例都是使用平时的使用用法,在Component上添加@Lazy注解,且让其实现InitializingBean接口,当Bean被加载时我们便能得知,看其是否会生效,示例如下:

@Lazy失效实例

声明一个Controller控制器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Controller
public class TestController implements InitializingBean{
    @Autowired
    private TestService testService;
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("testController Initializing");
    }
}

再声明一个Service服务类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Lazy
@Service
public class TestService implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("testService Initializing");
    }
}

启动程序后控制台输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
testService Initializing
testController Initializing

启动完Spring程序后输出了TestService里面打印的字符串。这就奇怪了,明明使用了@Lazy注解,但是却并没有其作用,在Spring启动项目时还是加载了这个类?简单来说,就是在DI注入的时候,获取容器中获取对应的Bean,Autowired按照默认类型获取Resource按照默认名称获取,所以才会导致延迟加载失效问题。

@Lazy有效实例

修改先前的Controller

启动后会发现,延迟加载失效问题解决了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Lazy
@Controller
public class TestController implements InitializingBean{
    @Autowired
    private TestService testService;
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("testController Initializing");
    }
}

3 BeanFactory和FactoryBean

  • BeanFactory是接口,提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范。
  • FactoryBean也是接口,为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类.

区别:

BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似

4 后置处理器

Spring提供了两种后处理bean的扩展接⼝:

  • BeanFactoryPostProcessor
    • 在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情
  • BeanPostProcessor
    • 在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处 理做⼀些事情

springBean 声明周期

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
“万物+”是 “互联网+”的深入和超越,人工智能与大数据的城市应用愈加密切 | 大咖周语录
“万物+”是 “互联网+”的深入和超越,人工智能与大数据的城市应用愈加密切 | 大咖周语录
数据猿
2018/04/19
7450
“万物+”是 “互联网+”的深入和超越,人工智能与大数据的城市应用愈加密切 | 大咖周语录
大咖周语录 | 黄明明全力押宝的投资对象是什么;富士康开始“关灯生产”?
数据猿导读 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上线下
数据猿
2018/04/20
5870
大咖周语录 | 黄明明全力押宝的投资对象是什么;富士康开始“关灯生产”?
物联网的本质是智能化 ,不能太夸大人工智能 ,数据将成为最重要生产资料 | 大咖周语录
物联网的本质是智能化 ,不能太夸大人工智能 ,数据将成为最重要生产资料 | 大咖周语录
数据猿
2018/04/19
7950
物联网的本质是智能化 ,不能太夸大人工智能 ,数据将成为最重要生产资料 | 大咖周语录
互联网不应成为实体经济替罪羊,要思考如何用好互联网 | 大咖周语录
数据猿导读 马云表示,未来社会的变革会越来越大,每一次技术变革都是就业的变革。互联网以后不再是高科技,而是必须的基础设施,所有行业都必须要用的。未来30年,这个世界不属于互联网公司,而属于那些用好互联
数据猿
2018/04/23
5440
互联网不应成为实体经济替罪羊,要思考如何用好互联网 | 大咖周语录
周鸿祎“呛声”李彦宏,互联网下半场的风口不是人工智能,而是物联网 | 大咖周语录
数据猿导读 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上线下
数据猿
2018/04/20
7120
周鸿祎“呛声”李彦宏,互联网下半场的风口不是人工智能,而是物联网 | 大咖周语录
我们正在进入一个软件定义的时代 要学会创造性地运用大数据和人工智能 | 大咖周语录
从云计算到大数据,人工智能已经具备了相对坚实的基础。不过,从当下人工智能的发展现状看,大部分的人工智能还停留在大数据分析阶段,距离真正的人工智能还有一定的距离。未来,我们正在进入一个软件定义的时代,其基本的特征表现在万物皆可互联,一切均可编程。 编辑 | 张宏 梅宏院士:大数据蓬勃发展,我们正在进入一个软件定义的时代 2017软博会,梅宏院士讲到,目前我们正在进入一个新的时代,不同的人,对这个时代赋予了不同的标签。 从基础设施角度,可以称之为互联网+时代; 从计算模式的角度,可以叫做云计算时代; 从
数据猿
2018/04/24
6890
我们正在进入一个软件定义的时代 要学会创造性地运用大数据和人工智能 | 大咖周语录
让ICO服务实体经济促进融合发展,掘金大数据,“三农”产业大有可为 | 大咖周语录
让ICO服务实体经济促进融合发展,掘金大数据,“三农”产业大有可为 | 大咖周语录
数据猿
2018/04/24
4980
让ICO服务实体经济促进融合发展,掘金大数据,“三农”产业大有可为 | 大咖周语录
数据是企业和社会发展的重要动力,AI从边缘发展到主流,未来十年信息技术将带来巨大“红利” | 大咖周语录
数据是企业和社会发展的重要动力,AI从边缘发展到主流,未来十年信息技术将带来巨大“红利” | 大咖周语录
数据猿
2018/04/19
7120
数据是企业和社会发展的重要动力,AI从边缘发展到主流,未来十年信息技术将带来巨大“红利” | 大咖周语录
中国联通CTO范济安:中国联通大数据发展与规划
<数据猿导读> 中国联通CTO范济安在2016年中国通信大数据大会上发表了以“中国联通大数据发展与规划”为主题的演讲。范济安表示,中国联通的大数据发展大致可以分为三个阶段。目前所面临的挑战,主要是怎样
数据猿
2018/04/19
1K0
中国联通CTO范济安:中国联通大数据发展与规划
“数据高铁”的时代或将来临,要关注人工智能发展的多层次性,推进智能经济发展 | 大咖周语录
“数据高铁”的时代或将来临,要关注人工智能发展的多层次性,推进智能经济发展 | 大咖周语录
数据猿
2018/04/25
7330
“数据高铁”的时代或将来临,要关注人工智能发展的多层次性,推进智能经济发展 | 大咖周语录
【周语录】用“大战略”迎接“大安全”时代的挑战
【周语录】用“大战略”迎接“大安全”时代的挑战
数据猿
2018/04/19
6420
【周语录】用“大战略”迎接“大安全”时代的挑战
文本大数据促进传媒产业融合,数据智慧触手可及,中国区块链技术尚处幼年生长期 | 大咖周语录
文本大数据促进传媒产业融合,数据智慧触手可及,中国区块链技术尚处幼年生长期 | 大咖周语录
数据猿
2018/04/19
6530
文本大数据促进传媒产业融合,数据智慧触手可及,中国区块链技术尚处幼年生长期 | 大咖周语录
大咖周语录 | “移动”写给友商联通的忠告,“学术界”对企业的“控诉”,令人深思!
数据猿导读 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上线下
数据猿
2018/04/20
6270
大咖周语录 | “移动”写给友商联通的忠告,“学术界”对企业的“控诉”,令人深思!
大咖周语录 | 沃森也是弱人工智能,强人工智能时代至少要等500年
数据猿导读 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上线下
数据猿
2018/04/20
6130
大咖周语录 | 沃森也是弱人工智能,强人工智能时代至少要等500年
大咖周语录 | BAT已成“过去式” ,实体店不借助大数据肯定被淘汰
、<数据猿导读> 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线
数据猿
2018/04/20
7560
大咖周语录 | BAT已成“过去式” ,实体店不借助大数据肯定被淘汰
探秘|顺丰菜鸟互撕背后:大数据争夺战已进入前所未有高度
“关闭数据接口的背后,本质上是顺丰和菜鸟对物流大数据的话语权争夺。” 事实上,伴随此次事件的爆发,让围绕大数据的利益纠葛上升到了一个前所未有的高度,“大数据争夺战”已经开始进入了一个小高潮。 《每日经
灯塔大数据
2018/04/08
1.1K0
探秘|顺丰菜鸟互撕背后:大数据争夺战已进入前所未有高度
大咖周语录 | 资金不够就别“碰”能源大数据,发展大数据产业别“犯傻”
<数据猿导读> 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上
数据猿
2018/04/20
6320
大咖周语录 | 资金不够就别“碰”能源大数据,发展大数据产业别“犯傻”
大咖周语录 | 李开复担忧大数据被巨头控制,鄂维南担忧企业过度“吞”人才
<数据猿导读> 对于大数据的概念以及大数据在各行业的应用,每个人心中都有不同的看法。小编每周都会整理大数据牛人们的精彩观点,让你在最短的时间获得最精的思想荟萃。后续,数据猿也会邀请更多行业大牛通过线上
数据猿
2018/04/20
7890
大咖周语录 | 李开复担忧大数据被巨头控制,鄂维南担忧企业过度“吞”人才
从生态角度认识大数据,做云计算公司要有想象力,通用人工智能将成为下一个攻坚点 | 大咖周语录
从生态角度认识大数据,做云计算公司要有想象力,通用人工智能将成为下一个攻坚点 | 大咖周语录
数据猿
2018/04/24
5590
从生态角度认识大数据,做云计算公司要有想象力,通用人工智能将成为下一个攻坚点 | 大咖周语录
未来的互联网发展,“场景”就是“战场”! | 大咖周语录
数据猿导读 马化腾在近日举行的贵阳数博会闭幕会上表示:未来互联网发展,更重要的一个要素是“场景“,我们称之为“战场”。 编辑 | abby 马化腾:未来的互联网发展,“场景”就是“战场”! 马化腾在近
数据猿
2018/04/24
6970
未来的互联网发展,“场景”就是“战场”! | 大咖周语录
推荐阅读
“万物+”是 “互联网+”的深入和超越,人工智能与大数据的城市应用愈加密切 | 大咖周语录
7450
大咖周语录 | 黄明明全力押宝的投资对象是什么;富士康开始“关灯生产”?
5870
物联网的本质是智能化 ,不能太夸大人工智能 ,数据将成为最重要生产资料 | 大咖周语录
7950
互联网不应成为实体经济替罪羊,要思考如何用好互联网 | 大咖周语录
5440
周鸿祎“呛声”李彦宏,互联网下半场的风口不是人工智能,而是物联网 | 大咖周语录
7120
我们正在进入一个软件定义的时代 要学会创造性地运用大数据和人工智能 | 大咖周语录
6890
让ICO服务实体经济促进融合发展,掘金大数据,“三农”产业大有可为 | 大咖周语录
4980
数据是企业和社会发展的重要动力,AI从边缘发展到主流,未来十年信息技术将带来巨大“红利” | 大咖周语录
7120
中国联通CTO范济安:中国联通大数据发展与规划
1K0
“数据高铁”的时代或将来临,要关注人工智能发展的多层次性,推进智能经济发展 | 大咖周语录
7330
【周语录】用“大战略”迎接“大安全”时代的挑战
6420
文本大数据促进传媒产业融合,数据智慧触手可及,中国区块链技术尚处幼年生长期 | 大咖周语录
6530
大咖周语录 | “移动”写给友商联通的忠告,“学术界”对企业的“控诉”,令人深思!
6270
大咖周语录 | 沃森也是弱人工智能,强人工智能时代至少要等500年
6130
大咖周语录 | BAT已成“过去式” ,实体店不借助大数据肯定被淘汰
7560
探秘|顺丰菜鸟互撕背后:大数据争夺战已进入前所未有高度
1.1K0
大咖周语录 | 资金不够就别“碰”能源大数据,发展大数据产业别“犯傻”
6320
大咖周语录 | 李开复担忧大数据被巨头控制,鄂维南担忧企业过度“吞”人才
7890
从生态角度认识大数据,做云计算公司要有想象力,通用人工智能将成为下一个攻坚点 | 大咖周语录
5590
未来的互联网发展,“场景”就是“战场”! | 大咖周语录
6970
相关推荐
“万物+”是 “互联网+”的深入和超越,人工智能与大数据的城市应用愈加密切 | 大咖周语录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档