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=""/>
相关文章推荐
- Spring学习(三)ioc工厂bean深入理解
- Spring学习----------深入理解Spring IoC容器
- Spring笔记――5.深入理解容器中的Bean
- Spring-----8、深入理解容器中的bean
- spring学习(三)—深入理解DIP、IoC、DI以及IoC容器
- Spring4深入理解IOC&DI03----Bean配置--SpEL,IOC 容器中 Bean 的生命周期
- Spring学习(三)ioc工厂bean深入理解
- 分布式缓存技术redis学习系列----深入理解Spring Redis的使用
- Java框架spring 学习笔记(一):SpringBean、ApplicationContext 容器、BeanFactory容器
- 【Spring揭秘】------ 第四章学习 Spring的IoC容器之BeanFactory 01
- spring Ioc 容器深入理解<一>
- 【Spring揭秘】------ 第四章学习 Spring的IoC容器之BeanFactory 02
- 【Spring学习24】容器扩展点:后置处理器BeanFactoryPostProcessor
- 深入理解Spring--动手实现一个简单的SpringIOC容器-注解版
- 7.8.2: 深入理解容器中的Bean---使用子Bean
- 分布式缓存技术redis学习系列----深入理解Spring Redis的使用
- spring源码学习之路---IOC容器初始化要义之bean定义载入
- 深入理解Spring4框架(三)——Bean
- 深入学习Spring源码---基本IOC容器初始化
- [原创]java WEB学习笔记98:Spring学习---Spring Bean配置及相关细节:如何在配置bean,Spring容器(BeanFactory,ApplicationContext),如何获取bean,属性赋值(属性注入,构造器注入),配置bean细节(字面值,包含特殊字符,引用bean,null值,集合属性list map propert),util 和p 命名空间