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);//正确,同时指定对象名和组件名
 
 
 
 
 
 
 
posted @ 2019-10-18 15:24  大冰块  阅读(118)  评论(0)    收藏  举报