title: spring-02_1
date: 2019-06-23 13:23:16
tags: spring-02_1
categories: spring
创建spring容器的三种方式
创建spring容器的案例代码(只有测试类部分)
/**
* 创建spring容器的三种方式
*/
public class TestUser {
public static void main(String[] args) {
test();
test2();
test3();
}
/**
* 第一种: 通过类路径加载
*/
private static void test() {
/**
* 1.加载配置文件创建spring容器,生成user(配置文件中id声明的名字为user)对象
* 其中参数为类路径(class路径),就是src下的路径,可以理解为相对src的相对路径,idea选中xml文件右键会有复制相对路径,那个就是对的
*/
System.out.println("test()");
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//2.获取context容器中的user对象
System.out.println("----------");
UserImpl user = (UserImpl) context.getBean("user");
//3.1调用方法,也可以通过property设置属性
user.add();
System.out.println(user.getName());
}
/**
* 第二种: 通过文件系统路径加载配置文件,就是绝对路径
* 选中beans.xml右键单击复制路径就是的
*/
private static void test2() {
System.out.println("test2()");
ApplicationContext context = new FileSystemXmlApplicationContext("D:\\IDEA_Codes\\spring\\day02\\src\\beans.xml");
UserImpl user = (UserImpl) context.getBean("user");
user.add();
System.out.println(user.getName());
}
/**
* 第三种: 使用BeanFactory
*/
private static void test3() {
System.out.println("test3()");
//这种方法加载配置文件是即时加载,对比ApplicationContext源码就知道了
BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("----------");
UserImpl user = (UserImpl) factory.getBean("user");
user.add();
System.out.println(user.getName());
/**
* 当BeanFactory使用下面这种方法时才是延时加载
* BeanFactory context = new XmlBeanFactory(new FileSystemResource("D:\\IDEA_Codes\\spring\\day02\\src\\beans.xml"));
*/
}
}
- 第一种(最常用): 利用
ApplicationContext接口
通过类路径加载配置文件生成spring容器同时在容器中生成以bean中的id属性值为名的对象例:
1. 下面就是创建spring容器加载配置文件的方式,就是下面这一行代码
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
2. 下面的就是beans.xml配置文件中加载spring容器第一种方式的对UserImpl类的配置内容
<bean id="user" class="service.impls.UserImpl">
<property name="name" value="licunli"></property>
</bean>
1. 过程: 加载配置文件生成spring容器并生成-[service.impls]-包下-[UserImpl类]-的对象-[user],同时给user对象的[name]属性赋值为["licunli"]
2. 不过要注意的是:
1. name属性在UserImpl类中已经声明好了
2. name属性必须要有set方法,不然赋值不会成功,会报错.
第二种: 通过文件系统路径创建spring容器,并加载配置文件,其中系统路径也就是绝对路径
第三种: 使用BeanFactory,跟第一种差不多,不过用BeanFactory的时候只能用相对路径,用绝对路径会报错
BeanFactory和ApplicationContext对比(这两个都是spring容器,用于去加载配置文件)
- BeanFactory采用延迟加载(已过时,现在也不延时加载了),第一次getBean时才会初始化Bean(也就是通过构造初始化对象)
- ApplicationContext是即时加载,是对BeanFactory的扩展,在它的基础上提供了更多的功能,包括以下几个方面:
国际化处理
事件传递
Bean自动装配
各种不同应用层的Context实现
- 关于BeanFactory和ApplicationContext两个容器加载配置文件时机的说明,如下:
1. 下面这种方法是即时记载无可非议,也就是一装载配置文件就初始化对象,跟单例模式里的饿汉式差不多
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
2. 对于BeanFactory,它现在也是即时加载,延时加载的方法过时了
1. 下面这样加载配置文件是延时加载,但是XmlBeanFactory()这个构造方法过时了已经
BeanFactory context = new XmlBeanFactory(new FileSystemResource("D:\\IDEA_Codes\\spring\\day02\\src\\beans.xml"));
2. 而这一种方法是即时加载,没过时,同时只能使用相对路径
BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
那么,spring内部创建对象的原理是什么呢?
- 原理其实就是反射(这东西很多地方用,我要去补习一下),过程如下:
解析xml文件,获取类名,id,属性等
通过反射,用类名创建对象
给创建的对象赋值
装配bean的三种方式
- 装配bean可以理解为把bean对象放在spring容器中,和创建spring容器连起来看就知道了,反正那一句话既创建了spring容器,还装配了bean对象
- 下面就表示装配了一个bean:
<bean id="user" class="service.impls.UserImpl">
<property name="name" value="licunli"></property>
</bean>
- 第一种: 就和上面的例子一样直接写就完事了,就相当于new了一个实现类,在java文件中加载配置文件创建了spring容器对象后直接通过getBean()方法获取这个对象就可以使用了
- 例子:
1. 装配bean对象
<bean id="user" class="service.impls.UserImpl"></bean>
2. 获取bean对象并使用
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserImpl user = (UserImpl)context.getBean("user");
user.add();
- 第二种: 通过静态工厂方法,就是把生成对象的代码放在静态工厂类中
- 例子:
1. 静态工厂类
public class UserFactory1 {
public static UserImpl createUserImpl() {
return new UserImpl();
}
}
2. xml文件中装配bean对象
<bean id="user1" class="service.UserFactory1" factory-method="createUserImpl">
</bean>
3. 获取bean对象并使用
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserImpl user = (UserImpl) context.getBean("user1");
user.add();
- 第三种: 通过实例工厂方法: 就是上面的静态工厂方法去掉了static
- 例子:
1. 实例工厂类
public class UserFactory2 {
public UserImpl createUserImpl() {
return new UserImpl();
}
}
2. xml中配置
<!--创建实例工厂类对象-->
<bean id="user2" class="service.UserFactory2" ></bean>
<!--创建bean对象-->
<bean id="user3" factory-bean="user2" factory-method="createUserImpl"></bean>
3. 获取bean对象并调用
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserImpl user3 = (UserImpl) context.getBean("user3");
user3.add();
Bean的作用域
- singleton(单例,默认,只有一个对象)
- 例子:
1. beans.xml配置文件
<bean id="user1" class="service.impls.UserImpl" scope="singleton"></bean>
2. 测试类
private static void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
UserImpl user = (UserImpl) context.getBean("user1");
user.add();
UserImpl user1 = (UserImpl) context.getBean("user1");
user.add();
System.out.println(user == user1);//true
}
- prototype(中文翻译是原型,可以理解为多例,多次调用getBean生成不同的对象,跟普通new差不多)
1. beans.xml配置文件
<bean id="user2" class="service.impls.UserImpl" scope="prototype"></bean>
2. 测试类
private static void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
UserImpl user = (UserImpl) context.getBean("user2");
user.add();
UserImpl user1 = (UserImpl) context.getBean("user2");
user.add();
System.out.println(user == user1);//false
}