Spring Bean
文章目录
内容参考《Spring5高级编程》。
Spring容器可以看作一个大型工厂,用于生产和管理Spring容器中的Bean。如果要使用这个工厂来生产和管理Bean,需开发者将Bean配置写在Spring的配置文件中,一般使用XML。
Bean的配置
属性和配置详见 Spring.io
Bean的实例化
在Spring框架中如果想使用Spring容器中的Bean,需要实例化。Bean被实例化后,才可以被Spring容器调用注入。
构造方法实例化
public class BeanClass{
public String message;
public BeanClass(){
message="构造方法实例化";
}
}
XML:
<bean id = "constructorInstance" class = "instance.BeanClass"/>
静态工厂实例化
需要在类中定义静态工厂方法来创建Bean,同时在XML配置中写明静态工厂方法的名称。
先介绍一下Spring中的bean,Spring只需要维护一个bean的实例,所有依赖对象使用同一个实例。Spring通过实现单例实例化模型,无需使用Singleton设计模式。
XML:
<bean id = "clinetService" class = "examples.ClientService" factory-method = "createInstance"/>
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
实例化工厂实例化
先定义一个工厂Bean,在定义其他由工厂类定义的Bean。
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
一个工厂类也可以包含多个工厂方法
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
Bean的作用域
当在 Spring 中定义一个 bean 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton。
singleton 作用域:Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
prototype 作用域:当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
Bean 的生命周期
理解 Spring bean 的生命周期很容易。
当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。
为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。
Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁 。
<bean id="helloWorld"
class="com.tutorialspoint.HelloWorld"
init-method="init" destroy-method="destroy">
//“”中为定义的方法名
<property name="message" value="Hello World!"/>
</bean>
Bean 后置处理器
Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。
BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。
注意这里的后置处理器会处理所有bean。
<bean id="test" class="project.dao.TestDaoImpl" />
<bean id="testdiservice" class="project.test.TestDIServiceImpl">
<property name="testDao" ref="test"/>
</bean>
<bean id="constructorinstance" class="project.instance.BeanClass"/>
<bean id="testsingleton" class="project.test.Helloworld" scope="prototype"/>
<bean id="helloworld" class="project.test.Helloworld" init-method="init" destroy-method="destroy">
<property name="message" value="Hello,world"/>
</bean>
BeforeInitialization:test
AfterInitialization:test
BeforeInitialization:testdiservice
AfterInitialization:testdiservice
BeforeInitialization:constructorinstance
AfterInitialization:constructorinstance
BeforeInitialization:helloworld
Bean is going through init
AfterInitialization:helloworld
Hello,world
Bean will destroy now.
Bean 定义继承
Spring Bean 定义的继承与 Java 类的继承无关,但是继承的概念是一样的。你可以定义一个父 bean 的定义作为模板和其他子 bean 就可以从父 bean 中继承所需的配置。
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>
<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!
bean继承,在实例化时传递了对应类型的父对象,由于默认单例化,传递的是同一个对象。
Spring 注入内部 Beans
正如你所知道的 Java 内部类是在其他类的范围内被定义的,同理,inner beans 是在其他 bean 的范围内定义的 bean。因此在 或 元素内 元素被称为内部bean。
类似内部类。初始化方式也类似。
Spring Beans 自动装配
- 使用@AutoWired自动装配时XML中应加入以下,@Autowired可以注解在属性上和setter方法上。@Autowired(required=true) 可以代替@Required。
<context:annotation-config/>
- 使用@Qualifier(“student1”)来区别注入哪一个bean实例。