Spring中的Bean

Spring中的Bean,第1张

Spring中的Bean

Bean在Spring和MVC中无所不在,将这个概念非常重要,下面来全面理解一下:

什么是Bean

1、Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化);

2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性;

3、规律:凡是子类及带有方法或属性的类都要加上注册Bean到Spring IoC的注解;(@Component , @Repository , @ Controller , @Service , @Configration)

4、把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了;

5、我们都在微博上@过某某,对方会优先看到这条信息,并给你反馈,那么在Spring中,你标识一个@符号,那么Spring就会来看看,并且从这里拿到一个Bean(注册)或者给出一个Bean(使用)。

6、Bean的本质是一个对象。

如何在spring中创建Bean

首先看一下spring中创建bean的方式

使用构造器创建Bean实例
使用构造器来创建Bean实例是最常见的情况,如果不采用构造注入,Spring底层会调用Bean类的无参构造器来创建实例,因此要求该Bean提供无参的构造器。在这种情况下,class元素是必须的,class属性的值就是Bean实例的实现类。Spring对Bean实例的所有属性执行默认初始化,即所有基本类型为0或false,引用类型为null。
接下来,Bean Factory会根据配置文件决定依赖关系,先实例化被依赖的Bean实例然后为注入依赖关系,最后将一个完整的Bean实例返回给程序。
如果采用构造注入,则要求配置文件为bean元素添加constructor-arg子元素,每个constructor-arg子元素配置一个构造器参数,Spring容器使用带对应参数的构造器来创建Bean实例。Spring调用构造器传入的参数即可用于初始化Bean的实例变量,最后也将一个完成的Bean实例返回给程序。

使用静态工厂方法创建Bean
使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类。除此之外,还需要使用factory-method属性来指定静态工厂方法,Spring将调用静态工厂方法返回一个Bean实例,得到Bean实例后,Spring后面的处理步骤与采用普通方法创建Bean完全一样。

调用实例工厂方法创建Bean
实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需要工厂类即可,而调用实例工厂方法则需要工厂实例。所以配置实例工厂方法与配置静态工厂方法基本相似,只有一点区别:配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂实例。
采用实例工厂方法创建Bean的bean元素时需要指定如下两个属性:
factory-bean:该属性的值为工厂Bean的id。
factory-method:该属性指定实例工厂的工厂方法。

两类注解

注解分为两类:

1、一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取Bean;

2、一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的@Autowired , @Resource配合到一起,把对象、属性、方法完美组装。

深入理解容器中的Bean

抽象Bean与子Bean

在实际开发中,有可能会出现这样的情况:随着项目越来越大,Spring配置文件出现了多个bean,配置具有大致相同的配置信息,只有少量信息不同,这将导致配置文件出现很多重复的内容。如果保留这些配置,则可能导致的问题是:
配置文件臃肿。
后期难以修改、维护。

为了解决上面问题,可以考虑把多个bean配置中相同的信息提取出来,集中成配置模板——这个配置模板并不是真正的Bean。因此Spring不应该创建该配置模板,于是需要为该bean配置增加abstract属性值为true表示这是个抽象Bean。

抽象Bean不能被实例化,Spring容器不会创建抽象Bean实例。抽象Bean的价值在于被继承,抽象Bean通常作为父Bean被继承。抽象Bean只是配置信息的模板,指定abstract为true即可阻止Spring实例化该Bean,因此抽象Bean可以不指定class属性。

将大部分相同信息配置成抽象Bean之后,将实际的Bean实例配置成该抽象Bean的子Bean即可。子Bean定义可以从父Bean继承实现类、构造参数、属性值能配置信息,除此之外,子Bean配置可以增加新的配置信息,并可以指定新的配置信息覆盖父Bean的定义。

通过为一个bean元素指定parent属性即可指定该Bean是一个子Bean,parent属性指定该Bean所继承的父Bean的id。子Bean无法从父Bean继承如下属性:depends-on、autowire、singleton、scope、lazy-init,这些属性只能从子Bean定义中获取,或采用默认值。

容器中的工厂Bean

此处的工厂Bean,与前面介绍的实例工厂Bean,或者静态工厂Bean有所区别:前面那些Bean是标准的工厂模式,Spring只是负责调用工厂方法来创建Bean的实例;此处的工厂Bean是Spring的一种特殊Bean,这种工厂Bean必须实现FactoryBean接口。

FactoryBean接口是工厂Bean的标准接口,把实现FactoryBean接口的工厂Bean部署在容器中后,如果程序通过getBean方法来获取它时,容器返回的不是FactoryBean实现类的实例,而是返回FactoryBean的产品。(即通过工厂所创建的对象被返回)

FactoryBean接口提供如下三个方法:
T getObject():负责返回该工厂Bean生成的Java实例。
Class getObjectType():返回该工厂Bean生成的Java实例的实现类。
boolean isSingleton():表示该工厂Bean生成的Java实例是否是单例模式。

配置FactoryBean与配置普通Bean的定义没有区别,但当程序向Spring容器请求获取该Bean时,容器返回该FactoryBean的产品,而不是返回该FactoryBean本身。所以,实现FactoryBean接口的最大作用在于:Spring容器返回的是该Bean实例的getObject()方法的返回值。而getObject()方法由开发者负责实现,所以返回什么类型就由开发者自己决定。

bean和BeanDefinition就类似Java中的实例和Class,是Spring对对象的一种增强,以BeanDefinition为模板创建出来的bean实例本质上也是对象,不过多了很多对象没有的功能,例如作用域,生命周期回调,各种各样的后置处理等等

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5710230.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存