配置形式:①基于 XML 文件的方式;②基于注解的方式
Bean 的配置方式:①通过全类名(反射)、②通过工厂方法(静态工厂方法 & 实例工厂方法)、③FactoryBean
IOC 和 DI
*IOC(Inversion of Control):其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式
*DI(Dependency Injection) — IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接
在Spring的IOC容器里配置Bean
只有SpringIOC容器本身实例化后,才能从IOC容器里获取Bean实例并使用。
Spring提供了两种类型的IOC容器实现(两种类型的配置方式是一样)
①BeanFactory:是Spring框架的基础设施,面向Spring本身
②ApplicationContext: 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory,提供了更多的高级特性. 是 BeanFactory 的子接口.
关于ApplicationContext的介绍
ApplicationContext的类图(可以看出ApplicationContext实质是个接口)
ApplicationContext 的主要实现类:
①ClassPathXmlApplicationContext:从 类路径下加载配置文件
②FileSystemXmlApplicationContext: 从文件系统中加载配置文件
子接口ConfigurableApplicationContext 的作用:扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力
ApplicationContext 在初始化上下文时就实例化所有单例的 Bean(注意:是单例的Bean)。
WebApplicationContext 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作
配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans">
<!-- 配置bean
class: bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean必须有无参的构造器
id: 标识容器Bean的名称,是唯一的,若id没有指定,Spring自动将权限定性类名作为Bean的名称
-->
<bean id="helloWorld" class="spring.bean.HelloWorld">
<!-- 设name的值赋为Spring(name对应setName) -->
<property name="name" value="Spring"></property>
</bean>
</beans>
测试类
public class Main {
public static void main(String[] args) {
//1、创建Spring的IOC容器
//ApplicationContext 代表IOC容器,实际是个接口
//ClassPathXmlApplication:是ApplicationContext接口的实现类。该实现类加载配置文件的方式:从类路径下
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
//2、从IOC容器中获取Bean实例
HelloWorld helloWorld=(HelloWorld) ctx.getBean("helloWorld");
//3、调用hello办法
helloWorld.hello();
}
}
从上面可以看出getBean()办法是由ApplicationContext 的父接口BeanFactory提供的,Bean除了用id获取还可以用类型获取
HelloWorld helloWorld=(HelloWorld)ctx.getBean("helloWorld");//通过id获取
HelloWorld helloWorld=ctx.getBean(HelloWorld.class);//通过类型获取
通过类型获取的缺点是当配置两个相同的bean,不知道获取哪个
比如
会报错(不知道获取哪个)
所以还是用第一种(明确指定了哪个bean)
依赖注入的方式
Spring支持3种依赖注入的方式
①属性注入
②构造器注入
③工厂方法注入(知道就行,不推荐)
属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象
属性注入使用 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 子节点指定属性值
属性注入是实际应用中最常用的注入方式
public void setName(String name)
{
System.out.println("setName:"+name);
this.name=name;
}
<bean id="helloWorld" class="spring.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
构造器注入:通过构造方法注入Bean的属性值或者依赖的对象(引用),保证了Bean实例在实例化后就可以使用
构造器注入在元素里声明属性,中没有name属性
创建一个Person对象
public class Person {
private String name;
private String sex;
private int age;
//第一种构造器
public Person(String name,int age) {
super();
this.name = name;
this.age = age;
}
//第二种构造器
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
Bean的配置文件
<!-- 通过构造方法来配置bean的属性 通过参数类型来区分构造器 -->
<bean id="person1" class="spring.bean.Person">
<constructor-arg value="John" type="java.lang.String"></constructor-arg>
<constructor-arg value="20" type="int"></constructor-arg>
</bean>
<bean id="person2" class="spring.bean.Person">
<constructor-arg value="John" type="java.lang.String"></constructor-arg>
<constructor-arg value="male" type="java.lang.String"></constructor-arg>
</bean>
Person person=(Person) ctx.getBean("person1");
System.out.println(person);
person=(Person) ctx.getBean("person2");
System.out.println(person);
运行结果