版权声明:新博客地址,欢迎大家一起学习交流 https://blog.csdn.net/qq_33665647/article/details/53178974 </div>
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
<div class="htmledit_views" id="content_views">
一,BeanFactory
BeanFactory顾名思义是Bean工厂的意思,采用的是工厂设计模式。Bean工厂的神圣职责就是负责Bean实例的创建、Bean实例之间依赖关系的装配及Bean实例的分发。这是Spring的核心技术之一,作为工厂,"看图生产"是必不可少的,同理,我们必须为Bean工厂提供一份"生产图纸"用于指导生产,这就是前面提到的Spring的配置文件(如applicationContext.xml),Spring并未规定配置文件的命名及数量,起什么名字都行,多个配置文件也可以。Spring容器在实例化时就会装载这些配置文件,并进行"看图生产"。
BeanFactory 接口位于类结构树的顶端, 它最主要的方法就是getBean(StringbeanName),该方法从容器中返回特定名称的Bean,BeanFactory 的功能通过其他的接口得到不断扩展。
BeanFactory 的类体系结构
ListableBeanFactory:该接口定义了访问容器中Bean 基本信息的若干方法,如查看Bean 的个数、获取某一类型Bean 的配置名、查看容器中是否包括某一Bean 等方法;
HierarchicalBeanFactory:父子级联IoC 容器的接口,子容器可以通过接口方法访问父容器;
ConfigurableBeanFactory:是一个重要的接口,增强了IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法;
AutowireCapableBeanFactory:定义了将容器中的Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
SingletonBeanRegistry:定义了允许在运行期间向容器注册单实例Bean 的方法;
BeanDefinitionRegistry:Spring 配置文件中每一个<bean>节点元素在Spring 容器里都通过一个BeanDefinition 对象表示,它描述了Bean 的配置信息。而BeanDefinitionRegistry 接口提供了向容器手工注册BeanDefinition 对象的方法。
-
ResourcePatternResolver resolver =
new PathMatchingResourcePatternResolver();
-
Resource res = resolver.getResource(
"classpath:com/baobaotao/beanfactory/beans.xml");
-
System.out.println(res.getURL());
-
BeanFactory bf =
new XmlBeanFactory(res);
-
System.out.println(
"init BeanFactory.");
-
-
Car car = bf.getBean(
"car",Car.class);
-
System.out.println(
"car bean is ready for use!");
-
car.introduce();
beans.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" xmlns:p=
"http://www.springframework.org/schema/p"
-
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
-
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
-
<bean id=
"car"
class=
"com.baobaotao.Car"
-
init-method=
"myInit"
-
destroy-method=
"myDestory"
-
p:brand=
"红旗CA72"
-
p:maxSpeed=
"200"
-
/>
-
<!-- bean id=
"car"
class=
"com.baobaotao.beanfactory.Car"
-
init-method=
"myInit"
-
destroy-method=
"myDestory"
-
p:brand=
"红旗CA72"/ -->
-
-
</beans>
二,ApplicationContext
如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/ context/beans.xml");
对于ClassPathXmlApplicationContext来说,"com/baobaotao/context/beans.xml"等同于"classpath: com/baobaotao/context/beans.xml"。
如果配置文件放置在文件系统的路径下,则可以优先考虑使用FilySystemXml ApplicationContext实现类:
ApplicationContext ctx = new FileSystemXmlApplicationContext("com/baobaotao/ context/beans.xml");
还可以指定一组配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext( new String[]{"conf/beans1.xml","conf/beans2.xml"});
当然FileSystemXmlApplicationContext和ClassPathXmlApplicationContext都可以显式使用带资源类型前缀的路径,它们的区别在于如果不显式指定资源类型前缀,将分别将路径解析为文件系统路径和类路径罢了。
在获取ApplicationContext实例后,就可以像BeanFactory一样调用getBean(beanName)返回Bean了。ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有"第一次惩罚"的问题。
-
package com.baobaotao.context;
-
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.context.annotation.Configuration;
-
-
import com.baobaotao.Car;
-
-
@Configuration
-
public
class Beans {
-
-
@Bean(name =
"car")
-
public Car buildCar() {
-
Car car =
new Car();
-
car.setBrand(
"红旗CA72");
-
car.setMaxSpeed(
200);
-
return car;
-
}
-
}
-
package com.baobaotao.context;
-
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-
import com.baobaotao.Car;
-
-
public
class AnnotationApplicationContext {
-
-
public static void main(String[] args) {
-
ApplicationContext ctx =
new AnnotationConfigApplicationContext(Beans.class);
-
Car car =ctx.getBean(
"car",Car.class);
-
}
-
}
前者可以被后者直接解析。