您的位置:首页 > 编程语言 > Java开发

spring学习之---深入理解容器中的Bean

2017-07-21 22:34 525 查看

1.抽象Bean与子Bean

抽象bean:把多个
<bean.../>
配置中相同的信息提取出来,集中成配置模板—这个模板并不是真正的Bean,因此spring不应该创建该配置模板。于是需要为该
<bean.../>
配置增加abstract=”true”。抽象Bean不能被实例化,spring容器不会创建抽象bean实例。抽象Bean的价值在于被继承,抽象Bean通常作为父Bean被继承。

子Bean定义可以从父Bean继承实现类、构造器参数、属性值等配置信息,子Bean可以增加新的配置信息,并可指定新的配置信息覆盖父Bean的定义。

指定parent属性即可指定该Bean是一个子Bean。

子Bean无法从父Bean继承如下属性:depends-on、autowire、singleton、scope、lazy-init。

2.Bean继承与Java继承的区别

spring中的子Bean和父Bean可以是不同类型,但Java中的继承则可保证子类是一种特殊的父类。

spring中的Bean的继承是实例之间的关系,因此主要表现为参数值的延续;Java中的继承是类之间的关系,只要表现为方法、属性的延续。

spring中的子Bean不可作为父Bean使用,不具备多态性;Java中的子类实例完全可当成父类实例使用。

3.容器中的工厂Bean

工厂Bean是spring的一种特殊Bean,这种工厂Bean必须实现FactoryBean接口。

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

FactoryBean接口提供如下三个方法:

T getObject():实现该方法负责返回该工厂Bean生成的Java实例。

Class
<?>
getObjectType():实现该方法返回该工厂Bean生成的Java实例的实现类。

boolean isSingleton():实现该方法表示该工厂Bean生成的Java实例是否为单例模式。

FactoryBean最大作用:spring容器并不是简单地返回该Bean的实例,而是返回该Bean实例的getObject()方法的返回值,而该方法则由开发者负责实现。

public class GetFieldFactoryBean implements FactoryBean{
private String targetClass;
private String targetField;
setter方法;
public Oject getObject() throws Exception{
Class<?> clazz = Class.forName(targetClass);
Field field = clazz.getField(targetField);
return field.get(null);
}
public Class<? extends Object> getObjectType(){
return Object.class;
}
public boolean isSingleton(){
return false;
}
}

<bean id="north" class="...GetFieldFactoryBean">
<property name="targetClass" value="java.awt.BorderLayout"/>
<property name="targetField" value="north"/>
</bean>


getObject方法的执行体使用反射先获取targetClass对应的Class对象,再获取targetField对应的类变量的值。

spring容器会自动检测容器中的所有Bean,如果发现某个Bean实现类实现了FactoryBean接口,spring容器就会在实例化该Bean、根据
<property.../>
执行setter方法之后,额外调用该Bean的getObejct()方法,并为该方法的返回值作为容器中的Bean。


System.out.printl(ctx.getBean(&north));


在Bean id前增加&符号,这将会让spring返回FactoryBean本身。

4.获得Bean本身的id

在某些极端情况下,业务要求程序员在开发Bean类时能预先知道该Bean的配置id,此时可借助spring提供的BeanNameAware接口,通过该接口即可提前预知该Bean的配置id。

BeanNameAware接口提供了一个方法:setBeanName(String name),该方法的name参数就是Bean的id,实现该方法的Bean类就可通过该方法来获得部署该Bean的id了。

当spring容器调用这个setter方法时,会把部署该Bean的id属性作为参数传入。

public class Chinese implements BeanNameAware{
private String beanName;
public void setBeanName(String name){
this.beanName = name;
}
public void info(){
System.out.println("部署该Bean时指定的id为:" + beanName);
}
}


5.强制初始化Bean

在极端的情况下,Bean之间的依赖不够直接。比如,某个类的初始化块中使用其他Bean,spring总是先初始化主调Bean,当执行初始化块时,被依赖Bean可能还没实例化,此时将引发异常。

为了显示指定被依赖Bean在目标Bean之前初始化,可以使用depends-on属性,该属性可以在初始化主调Bean之前,强制初始化一个或多个Bean。

<bean id="beanOne" class="" depends-on="beanTwo"/>
<bean id="beanTwo" class=""/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐