基于Properties文件读取Bean定义

[b]1.bean读取方式一:[/b]
Bean配置在内部是通过实习了BeanDefination接口的类实例来表现的,Bean的配置不仅存储了bean自己的信息,而其也体现了bean的依赖信息。对于任何同时实现了beanDefinationRegistery接口的BeanFantory类,你可以通过配置文件中读取Bean定义,通过PropertiesBeanDefinitionReader类就是一种方式。还又另一种方式,下次介绍。
[b]2.看PropertiesBeanDefinitionReader源代码:[/b]
public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader {
..............................
}

[b]主要方法:[/b]
[b]loadBeanDefinitions();加载bean属性定义从一个properties文件,这个文件资源被封装到一个带编码方式的资源,并按该编码方式解析文件,prefix是过滤的前缀,可以为空。返回取得的bean的数量[/b]
public int loadBeanDefinitions(EncodedResource encodedResource, String prefix) throws BeansException {
Properties props = new Properties();
try {
InputStream is = encodedResource.getResource().getInputStream();
try {
if (encodedResource.getEncoding() != null) {//运用属性持久器[b](这里用的是:DefaultPropertiesPersister)[/b]以流的形式,并按制定的编码方式加载bean属性
getPropertiesPersister().load(props, new InputStreamReader(is, encodedResource.getEncoding()));
}
else {//
getPropertiesPersister().load(props, is);
}
}
finally {//关闭流
is.close();
}//调用下面介绍的另一个重要方法,去注册bean
return registerBeanDefinitions(props, prefix, encodedResource.getResource().getDescription());
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("Could not parse properties from " + encodedResource.getResource(), ex);
}
}

[b]registerBeanDefinitions();解析出bean的名字,让后调用注册方法,注册beanName到工厂,返回注册过的bean的数量[/b]
public int registerBeanDefinitions(Map map, String prefix, String resourceDescription)
throws BeansException {

if (prefix == null) {
prefix = "";
}
int beanCount = 0;

for (Iterator it = map.keySet().iterator(); it.hasNext();) {
Object key = it.next();
if (!(key instanceof String)) {
throw new IllegalArgumentException("Illegal key [" + key + "]: only Strings allowed");
}
String keyString = (String) key;
if (keyString.startsWith(prefix)) {
// Key is of form: prefix<name>.property
String nameAndProperty = keyString.substring(prefix.length());
// Find dot before property name, ignoring dots in property keys.
int sepIdx = -1;
int propKeyIdx = nameAndProperty.indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX);
if (propKeyIdx != -1) {
sepIdx = nameAndProperty.lastIndexOf(SEPARATOR, propKeyIdx);
}
else {
sepIdx = nameAndProperty.lastIndexOf(SEPARATOR);
}
if (sepIdx != -1) {
String beanName = nameAndProperty.substring(0, sepIdx);
if (logger.isDebugEnabled()) {
logger.debug("Found bean name '" + beanName + "'");
}
if (!getBeanFactory().containsBeanDefinition(beanName)) {
// If we haven't already registered it...
registerBeanDefinition(beanName, map, prefix + beanName, resourceDescription);
++beanCount;
}
}
else {
// Ignore it: It wasn't a valid bean name and property,
// although it did start with the required prefix.
if (logger.isDebugEnabled()) {
logger.debug("Invalid bean name and property [" + nameAndProperty + "]");
}
}
}
}

return beanCount;
}

[b]registerBeanDefinition();得到bean的所有属性值,并加一前缀,并讲bean注册到工厂[/b]
protected void registerBeanDefinition(String beanName, Map map, String prefix, String resourceDescription)
throws BeansException {
//bean的属性
String className = null;
String parent = null;
boolean isAbstract = false;
boolean singleton = true;
boolean lazyInit = false;

ConstructorArgumentValues cas = new ConstructorArgumentValues();
MutablePropertyValues pvs = new MutablePropertyValues();

for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = StringUtils.trimWhitespace((String) entry.getKey());
if (key.startsWith(prefix + SEPARATOR)) {
String property = key.substring(prefix.length() + SEPARATOR.length());
if (isClassKey(property)) {
className = StringUtils.trimWhitespace((String) entry.getValue());
}
else if (PARENT_KEY.equals(property)) {
parent = StringUtils.trimWhitespace((String) entry.getValue());
}
else if (ABSTRACT_KEY.equals(property)) {
String val = StringUtils.trimWhitespace((String) entry.getValue());
isAbstract = TRUE_VALUE.equals(val);
}
else if (SINGLETON_KEY.equals(property)) {
String val = StringUtils.trimWhitespace((String) entry.getValue());
singleton = (val == null) || TRUE_VALUE.equals(val);
}
else if (LAZY_INIT_KEY.equals(property)) {
String val = StringUtils.trimWhitespace((String) entry.getValue());
lazyInit = TRUE_VALUE.equals(val);
}
else if (property.startsWith(CONSTRUCTOR_ARG_PREFIX)) {
if (property.endsWith(REF_SUFFIX)) {
int index = Integer.parseInt(property.substring(1, property.length() - REF_SUFFIX.length()));
cas.addIndexedArgumentValue(index, new RuntimeBeanReference(entry.getValue().toString()));
}
else {
int index = Integer.parseInt(property.substring(1));
cas.addIndexedArgumentValue(index, readValue(entry));
}
}
else if (property.endsWith(REF_SUFFIX)) {
// This isn't a real property, but a reference to another prototype
// Extract property name: property is of form dog(ref)
property = property.substring(0, property.length() - REF_SUFFIX.length());
String ref = StringUtils.trimWhitespace((String) entry.getValue());

// It doesn't matter if the referenced bean hasn't yet been registered:
// this will ensure that the reference is resolved at runtime.
Object val = new RuntimeBeanReference(ref);
pvs.addPropertyValue(property, val);
}
else{
// It's a normal bean property.
pvs.addPropertyValue(property, readValue(entry));
}
}
}

if (logger.isDebugEnabled()) {
logger.debug("Registering bean definition for bean name '" + beanName + "' with " + pvs);
}

// Just use default parent if we're not dealing with the parent itself,
// and if there's no class name specified. The latter has to happen for
// backwards compatibility reasons.
if (parent == null && className == null && !beanName.equals(this.defaultParentBean)) {
parent = this.defaultParentBean;
}

try {//这里用解析出的属性,构建一个beanDefination的基类实例
AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
parent, className, getBeanClassLoader());
bd.setAbstract(isAbstract);
bd.setSingleton(singleton);
bd.setLazyInit(lazyInit);
bd.setConstructorArgumentValues(cas);
bd.setPropertyValues(pvs);
//这里讲该bean注册到beanFantory
getBeanFactory().registerBeanDefinition(beanName, bd);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(resourceDescription, beanName, className, ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(resourceDescription, beanName, className, err);
}
}

[code="java"][/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值