好吧,拖了很久没写的spring。我们先从最简单的开始吧。
版本:
springFramework 4.2.6RELEASE
JDK 1.8
spring像个大水桶,什么都装。先来看一段简单的代码。
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanTest.xml"));
Hello hello = (Hello) factory.getBean("Hello");
System.out.println(hello.getName());
}
beanTest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="Hello" class="demo.spring.Hello"></bean>
</beans>
Hello实体类:
public class Hello {
private String name = "hello spring";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
输出
这恐怕是spring容器最简单的用法了。
注意到,XmlBeanFactory被标记为@Deprecated。看了一下spring源码里面的注释,是这样说的:
Convenience extension of DefaultListableBeanFactory that reads bean definitions from an XML document. Delegates to XmlBeanDefinitionReader underneath; effectively equivalent to using an XmlBeanDefinitionReader with a DefaultListableBeanFactory.
The structure, element and attribute names of the required XML document are hard-coded in this class.
For advanced needs, consider using a DefaultListableBeanFactory with an XmlBeanDefinitionReader The latter allows for reading from multiple XML resources and is highly configurable in its actual XML parsing behavior.
简单来说就是,XmlBeanFactory是DefaultListableBeanFactory的一个简便的泛化。实际上等于使用XmlbeanDefinitionReader配合DefaultListableBeanFactory使用。这个类写死了xml的结构,元素和属性名。为了更高级的需求,using a DefaultListableBeanFactory with an XmlBeanDefinitionReader.
我们来看XmlBeanFactory这个类,
@Deprecated
@SuppressWarnings({"serial", "all"})
public class XmlBeanFactory extends DefaultListableBeanFactory {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
这个类其实用处也不大。我们可以通过以下代码来做简单的替换:
DefaultListableBeanFactory factory1 = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory1);
reader.loadBeanDefinitions(new ClassPathResource("beanTest.xml"));
所以按照他的说法,这样能够支持更多 形式的xml资源。
好像有点跑题了,不过spring就是这样,到处充满了设计,到处都是封装,每看到一处都会小心翼翼地看他还有没有其他我们没有想到的东西。不过我觉得,有些封装的东西,我们不必每个细节都了解得很清楚,知道原理,如果需要的时候能够快速通过源码定位到我们需要的东西,这样就行了。像上文的 new ClassPathResource(“”),spring实际上会返回一个封装好的InputStreamSource。这个InputStreamSource接口只有一个方法getInputStream()。我们可以通过一个InputStreamSource来获得输入流。像这样:
InputStreamSource resource = new ClassPathResource("beanTest.xml");
InputStream inputStream = resource.getInputStream();
至于Resource是怎么从xml到inputStream的,是封装的东西。我们可以挑一个类来看一下,比如ClassPathResource:
public InputStream getInputStream() throws IOException {
InputStream is;
if(this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
} else if(this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
} else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if(is == null) {
throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist");
} else {
return is;
}
}
只是封装了Class和ClassLoader的底层调用。是不是相当简单?
至于这个Resource的类图,我简单画了个类图:
当然这个只是简单把ClassPathResource的继承关系图画了出来,InputStreamSource还有很多子接口和子类。
你看,又扯远了,我们继续看reader.loadBeanDefinitions()这个操作。好吧,感觉这个东西又是深不见底,我们留到下回说吧。我要去洗澡了。
其实如果简单的话我们可以就把他当成一个注册的过程。当然里面还是有值得我们探究的东西的。
好吧,这篇就当做简单的开端吧,好戏在后头呢嘿嘿。