Spring 的 IoC,即控制反转,程序中由 Spring 来管理对象,当需要使用某个对象时,直接通过 IoC 容器来获取对象,并通过 DI 来完成对象之间的注入关系。Spring 中的 beanbean 是根据 scope 来生成的,表示 bean 的作用域,scope 有 4 种类型:singleton,单例,表示通过 Spring 容器获取的该对象是唯一的;prototype,原型,表示通过 Spring 容器获取的对象都是不同的;request,请求,表示在一次 HTTP 请求内有效;session,会话,表示在一个用户会话内有效。后两种只适用于 Web 项目,大多数情况下,我们只会使用 singleton 和 prototype 两种 scope,并且 scope 的默认值是 singleton。我们通过一个例子来学习这两种配置的区别。
(1)创建 User 实体类public class User {
private int id;
private String name;
private int age;
public User() {
System.out.println(“创建了User对象”);
}
}
(2)在 spring.xml 配置 User 的实例化 bean
(3)测试类中通过 Spring 容器获取两个 User 实例化对象 user1 和 user2,并且通过 == 方法判断是否为同一个对象ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring.xml”);
User user = (User) applicationContext.getBean(“user”);
User user2 = (User) applicationContext.getBean(“user”);
System.out.println(user == user2);
运行结果如下图所示。
看到结果打印 true,并且 User 的构造函数只执行了一次,表示 user1 和 user2 是同一个对象,因此 scope 默认值为 singleton,即默认通过 Spring 容器创建的对象都是单例模式。修改 spring.xml 中的配置,将 scope 改为 prototype。
执行代码,结果如下图所示。
可以看到,调用了两次构造函数,并且 == 的结果为 false,表示现在的 user1 和 user2 是两个对象。点击这里了解《Spring 全家桶》Spring 的继承Spring 的继承与 Java 的继承不一样,但思想很相似,子 bean 可以继承父 bean 中的属性。看到这里,你可能会有这样的疑问:子 bean 可以继承父 bean 中的方法吗?其实这里不存在方法的继承,Spring 的继承是在对象层面进行操作的,即两个 bean 来自同一个类,因此方法是一样的,不存在继承关系,具体使用如下所示。
(1)在 spring.xml 中配置两个 User bean,并建立继承关系。
(2)运行代码,结果如下。User user2 = (User) applicationContext.getBean(“user2”);
System.out.println(user2);
可以看到,创建了两个 User 对象 user1 和 user2,并且 user2 继承了 user1 的所有属性。user2 在继承 user1 所有属性的基础之上,还可以对属性进行覆盖,直接在 spring.xml 中添加 property 即可。
再次运行代码,结果如下图所示。name 属性已经被修改为李四,完成覆盖。有读者可能会问,Spring 中的 bean 能不能在不同类之间继承?答案是可以的,但是需要这两个类的属性列表完全一致,否则会报错,实际开发中并不会使用到这种方式。Spring 的依赖与继承类似,依赖也是 bean 和 bean 之间的一种关联方式,配置依赖关系后,被依赖的 bean 一定先创建,再创建依赖的 bean,我们还是通过代码来理解。(1)创建 Car 实体类public class Car {
private int id;
private String brand;
public Car() {
System.out.println(“创建了Car对象”);
}
}
(2)在 spring.xml 中配置 User bean、Car bean
(3)测试类中获取两个 beanApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring.xml”);
User user = (User) applicationContext.getBean(“user”);
Car car = (Car) applicationContext.getBean(“car”);
结果如下图所示。看到结果,先创建 User,后创建 Car,这是由 spring.xml 中 bean 的配置顺序来决定的,先到先得,先配置 User bean,因此先创建了 User 对象。现在修改 spring.xml 配置,User 依赖 Car,设置 depends-on 属性,如下所示。
再次运行代码,看到结果,先创建 Car,后创建 User,因为 User 依赖于 Car,所以必须先创建 Car 对象,User 对象才能完成依赖。Spring 读取外部资源在实际开发中,数据库配置一般会保存在 Properties 文件中方便维护,如果使用 Spring 容器来生成数据源对象,如何读取到 properties 配置文件中的内容?(1)创建 jdbc.propertiesdriverName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/myTest?useUnicode=true&characterEncoding=UTF-8
user = root
pwd = root
(2)spring.xml 中配置 C3P0 数据源
<context:property-placeholder location=“classpath:jdbc.properties”></context:property-placeholder>