SpringDay02_ioc
IOC:(Inversion(反转) Of Control):控制反转;
控制:资源的获取方式
主动式:(要什么资源都需要自己创建)
BookServlet{
BookService bs = new BookService();
AirPlane ap = new AirPlane(); 复杂对象的创建 工程负担较重
}
被动式:资源的获取不需要自己创建,而是交给一个容器来创建和设置;
BookServlet{
BookService bs ;
public void test(){
bs.checkout();
}
}
容器: 主动的new资源变为被动的接收资源(按需分配) 管理所有的组件(有功能的类);假设,BookServlet受容器管理,BookServeice也受容器管理;容器可以自动的探查出那些组件(类)需要用到另一些组件(类);容器帮我们创建BookService对象,并把BookService对象赋值过去;
DI:(Dependency Injection)依赖注入;
容器能知道那个组件(类)运行的时候,需要另外一个组件(类);容器通过反射的形式,将容器中准备好的BooeService对象注入(利用反射给属性赋值)到BookServlet中;
只要容器管理的组件,都能使用容器提供的所有功能
HelloWorld实例
框架流程:
1) 导包
核心容器
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
Spring 运行时依赖的一个日志包,没有就报错
commons-logging-1.1.3.jar
2)写配置
基本类型直接使用
<property name="name" value="jack"></property>自动进行类型转换
进行复杂赋值时
<property name="name" >
<value></value>
</property>
引用类型赋值(引用其他bean,引用内部bean)
<bean id="car01" class="com.lmh.bean.Car">
<property name="carName" value="bmw"></property>
<property name="color" value="black"></property>
<property name="price" value="30000"></property>
</bean>
<bean id="person06" class="com.lmh.bean.Person">
<!-- ref:代表引用外部的bean
car = ioc.getBean("car01")-->
<property name="car" ref="car01"></property>
<property name="car">
<!-- 对象我们可以使用bean标签创建 car = new Car() 引用内部bean,不能被获取,只能内部使用,内部类添加id属性,不能被调用 -->
<bean class="com.lmh.bean.Car">
<property name="carName" value="audi"></property>
</bean>
</property>
</bean>
3)测试
@Test
public class IOCTest {
/**
* 存在的问题:
* 1) src、 源码包开始的路径,称为类路径的开始
* 所有源码包里面的东西都被合并放在类路径里面
* java:/bin/
* web:/WEB-INF/classes/
* 2) 导包commons-logging-1.1.3.jar(依赖)
* 3) 先导包在创建ioc.xml配置文件
* 4) Spring的容器接管了标志了s的类
*/
/**
* 细节问题:
* 1) ApplicationContext(IOC容器的接口)
* 2) 给容器中注册一个组件,我们从容器中根据ID能够拿到这个类的对象
* 组件的创建工作,是容器完成的
* Person对象什么时候创建完成?
* 容器中的对象在容器创建完成时就已经创建好了
* 3) 同一个组件在ioc容器中是单实例的;
* 4)容器中如果没有这个组件,获取组件时会报错
* org.springframework.beans.factory.NoSuchBeanDefinitionException:
*No bean named 'person03' is defined
*5)ioc容器在创建这个组件(类)对象的时候,(property)会利用setter方法为javaBean的属性进行赋值
*6)javaBean的属性名是有什么决定的?
* getter和setter方法是属性名,set***,***首字母小写就是属性名;
* 因此所有的getter和setter都自动生成
*/
@Test
public void test() {
/**
* 从容器中拿到这个组件 ApplicationContext:代表ioc容器
* ClassPathXmlApplicationContext:当前应用的xml配置文件在ClassPath下
* 根据spring的配置文件得到ioc容器对象
* ApplicationContext ioc = new ClassPathXmlApplicationContext("com/lmh/bean/IOC.xml");
*/
ApplicationContext ioc = new ClassPathXmlApplicationContext("IOC.xml");
// 容器帮我们创建对象,我们直接调用就可以
Person person = (Person) ioc.getBean("person01");
Object bean2 = ioc.getBean("person01");
System.out.println(person==bean2);//true,同一个组件在ioc容器中是单实例的;
Object bean = ioc.getBean("person03");//容器中如果没有这个组件,获取组件时会报错No bean named 'person03' is defined
}
添加@test注解时,如果报错的话,设置java编译器的版本:Window>>Preferences>>java>>compiler进行修改
当配置文件在src下时,我们使用 new ClassPathXmlApplicationContext("ioc.xml");
当配置文件在其他文件夹中,使用 new FileSystemXmlApplicationContext("F://ioc.xml");
不同情况下,使用不同的方法获取组件对象
ioc配置文件有两个对象
<bean id="person01" class="com.lmh.bean.Person">
<!-- 使用property给对象的属性进行赋值 name: 指定属性名 value: 为属性赋值 -->
<property name="name" value="tom"></property>
<property name="gender" value="man"></property>
<property name="age" value="18"></property>
<property name="email" value="tom@qq.com"></property>
</bean>
<bean id="person02" class="com.lmh.bean.Person">
<!-- 使用property给对象的属性进行赋值 name: 指定属性名 value: 为属性赋值 -->
<property name="name" value="jack"></property>
<property name="gender" value="woman"></property>
<property name="age" value="22"></property>
<property name="email" value="jack@qq.com"></property>
</bean>
根据bean的类型从ioc容器获取bean的实例:
如果ioc容器中这个类型的bean有多个,按照类型查找或报错
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
expected single matching bean but found 2: person01,person02
Person bean = ioc.getBean(Person.class);//报错
Person bean2 = ioc.getBean("person02",Person.class);//正确,同时指定对象名和组件名

浙公网安备 33010602011771号