Spring提供了两种容器类型:BeanFactory和ApplicationContext
BeanFactory:BeanFactory是基础类型的IoC容器,提供完整的IoC服务支持.如果没有特殊指定,默认采用延迟初始化策略(lazy-load).也就是说bean只有在真正使用的情况下才会被初始化以及依赖注入操作,所以Bean初期启动速度较快,在对于资源有限,并且功能要求不严格的场景,BeanFactory是合适的选择
ApplicationContext:ApplicationContext在BeanFactory的基础上构建,是相对高级的容器实现,除了拥有BeanFactory的功能外,ApplicationContext还提供了更高级的特性.ApplicationContext和BeanFactory不同之处还在于ApplicationContext在初始化容器时会完成所有bean的初始化
BeanFactory是一个接口,DefaultListableBeanFactory是一个常用的BeanFactory的实现类。DefaultListableBeanFactoryy除了间接实现BeanFactory接口,还实现了BeanDefinitionRegistry接口,该接口在BeanFactory中担当Bean注册管理的角色,而在容器中每个bean对象都有一个对应的BeanDefinition的实例与之对应。抽象类AbstractBeanDefinition是BeanDefinition接口的一个实现,而AbstractBeanDefinition有三个子类,一个是RootBeanDefinition一个是ChildBeanDefinition另一个是GenericBeanDefinition,这三个子类有什么不同呢
下面这个例子演示了使用BeanFactory作为IoC容器
public static void main(String[] args) {
//首先初始化registry在IOC容器中用于真正的bean管理
DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
//通过bindViaCode得到
BeanFactory container = (BeanFactory) bindViaCode(beanRegistry);
Student student= (Student) container.getBean("student");
System.out.println(student.toString());
}
public static BeanFactory bindViaCode(BeanDefinitionRegistry registry) {
//AbstractBeanDefinition是bean的对应实例
AbstractBeanDefinition student = new RootBeanDefinition(Student.class, 2, true);
AbstractBeanDefinition people = new RootBeanDefinition(People.class, 2, true);
registry.registerBeanDefinition("student", student);
registry.registerBeanDefinition("people", people);
//people初始化需要的构造函数参数
ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addIndexedArgumentValue(0, "fristname");
args.addIndexedArgumentValue(1, "lastname");
people.setConstructorArgumentValues(args);
//设置student的age属性
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("age", 20);
student.setPropertyValues(propertyValues);
return (BeanFactory) registry;
}
上面这段代码首先初始化Registry是IoC容器中bean真正的管理者,而new RootBeanDefinition(Student.class, 2, true);是bean对应的实例,如果构造器需要传参可以使用ConstructorArgumentValues对象,而对于属性可以使用MutablePropertyValues进行初始化
使用注解的方式
在spring.xml中加入如下配置
<context:component-scan base-package="com.spring.ioc.factory"/>
在Student的类上加上component注释
@Component
public class Student {
private int age;
@Autowired
private Computer computer;
用spring.xml配置文件
案例
public static void main(String[] args) {
DefaultListableBeanFactory beanRegistry=new DefaultListableBeanFactory();
BeanFactory container=bindViaXMLFile(beanRegistry);
Teacher teacher= (Teacher) container.getBean("teacher");
teacher.showMe();
}
public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry){
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(registry);
reader.loadBeanDefinitions("classpath:spring.xml");
return (BeanFactory)registry;
}
main函数
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Student student = context.getBean(Student.class);
System.out.println(student);
}