适合新手的SpringIoc详解

Spring是轻量级的IoC和AOP框架

SpringIoC是通过DI(dependency Injection)依赖注入的方式实现类与类之间的依赖关系的,以达到解耦的作用.

依赖方式:

一.基于xml文件的配置的注入:

*构造注入
*setter注入
*接口注入

针对于不同类型形参是怎么注入的呢?(常见POJO 对象注入DI)

setter方法
<bean id="userServiceSettersDI" class="com.mummy.spring.service.impl.UserService" destroy-method="close">
    <property name="userDao" ref="userDao2"></property>
    <property name="strValue" value="I Am String"></property>
    <property name="listValue">
        <list>
            <value>list1</value>
            <value>list2</value>
            <value>list3</value>
        </list>
    </property>
    <property name="setValue">
        <set>
            <value>set1</value>
            <value>set2</value>
            <value>set3</value>
            <value>set4</value>
        </set>
    </property>
    <property name="strArrayValue">
        <list>
            <value>strArray1</value>
            <value>strArray2</value>
            <value>strArray3</value>
            <value>strArray4</value>
        </list>
    </property>
    <property name="setValue">
        <set>
            <value>set1</value>
            <value>set2</value>
            <value>set3</value>
            <value>set4</value>
        </set>
    </property>
    <property name="mapValue">
        <map>
            <entry key="key1" value="1"></entry>
            <entry key="key2" value="2"></entry>
            <entry key="key3" value="3"></entry>
        </<map>>
    </property>
</bean>

2.scope属性:bean实例对象的scope作用域范围 “singleton/prototype”

singleton 仅仅初始化一次,创建一个实例A a = new A();
prototype 每次对bean的访问都会创建一个新的实例 A a0 = new A(); A a1 = new A();
<bean id="userDao2Prototype" class="com.mummy.spring.dao.impl.UserDao2" scope="prototype"></bean>

bean延迟加载(容器启动加载,还是实例化的时候加载呢?默认是在容器初始化的时候就加载好了,延迟加载时在实例化的时候才加载)

1.bean延迟加载的几种方式:lazy-init=”false|true”

    默认方式:lazy-init="false"(容器加载的时候就实例化出所有被注册的beanClass)      
    lazy-init="true"

    System.out.println("---容器已启动---");
    ac.getBean("userAnOther");
    //不使用lazy-init="true",报错cano'tLoadBeanClassException
    //使用了lazy-init="true" 
    输出:---容器已启动--- 
    此方式只有在实例化此beanClass的时候才报错cannotLoadBeanClassException

2.应用场景:当A类应用B类,A类就需要延迟加载;如果所有的bean都需要延迟加载,在头文件中写入:default-lazy-init=”true”

3.Spring容器会自动向bean中注入依赖–>自动装配(为什么要自动装配呢?减轻编程人员在applicatonContext.xml配置bean,还要指明依赖关系)

自动装配就是为了让我们不要指明依赖关系,而是通过属性的设置来达到相同的效果(属性备注为@Autowired)

在spring的配置文件applicationContext.xml的要被注册bean中加上一个属性:autowired="byName|byType|constructor"
byName和byType都是通过setter方法注入的

byName 定义被依赖的bean名称需要与类中对应的名称一致,就会匹配依赖关系
    在service类中依赖具体Dao实现的对象;private IUserDao userDao; 在配置文件中被注册的背依赖类bean的id则必须为userDao;实际上就是省略了userDao的property属性<property name="userDao" ref="userDaoAutowired"/>
byType 通过定义的依赖bean的类型来进行匹配,依赖的对象可以是接口本身也可以是接口的实现

1.在配置文件中有多个接口的实现,他们也都可以通过byType注入到成员变量中去,容易报错:

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.mummy.spring.dao.IUserDaoAutowired] is defined: expected single matching bean but found 2: userDao,userDaoAutowire

2.两个同类型怎么解决呢?

    在不想要被依赖的的bean上加上autowire-candidate="false":放弃候选

结论:建议不要在配置文件中使用自动装配,虽然可以减少配置文件,但是不利于维护

1.单个xml文件的读取:

读取配置文件;ApplicatonContext ac = new ClassPathXmlApplicatonContext("ApplicationContext-autowired.xml");    

2.多个xml文件的读取:

    ApplicatonContext ac = new ClassPathXmlApplicatonContext("ApplicationContext-autowired.xml","ApplicationContext.xml");
    等价于:
    String[] configFiles = new String[]{"ApplicationContext-autowired.xml","ApplicationContext.xml"};
    ApplicatonContext ac = new ClassPathXmlApplicatonContext(configFiles);
3.用约定的方式(约定)
ApplicatonContext ac = new ClassPathXmlApplicatonContext("ApplicationContext*.xml");

4.读取一个总的配置文件,其他配置都被包含在这一个总配置文件中
ApplicatonContext ac = new ClassPathXmlApplicatonContext("ApplicationContext-all.xml");
ClassPathXmlApplicatonContext:是指在编译目录的根文件(去类的编译路径读取配置文件);如果是web项目,项目编译之后的所有的java文件都放在WEB-INF/classes/...下面,

5.文件系统读取 (实现不同)
ApplicationContext ac = new FileSystemXmlApplicationContexxt();
//源文件夹在window系统下会被转成普通文件夹

二.通过注解配置

DI的方式有三种:setter依赖,constructor依赖,interface依赖(少见)

通过set方法或构造方法进行依赖注入,必须在依赖类中提供被依赖类实例的setter方法和构造方法.
在Spring的配置文件中,注册好需要被管理的bean类,格式:>>
< bean id=”userDao” class=”com.mummy.spring.dao.UserDao” >< / bean >
上面这句话的意思就是在程序中创建一个实例;UserDao userDao = new UserDao();但是他的创建由Spring容器来管理创建
在需要依赖的bean中通过需要依赖的对象,进行注入即可,
例如:service依赖于userDao类的实例
(构造方法注入)
< bean id=”userService” class=”com.mummy.spring.service.UserService”>
< constructor-arg ref=”userDao”/>
< /bean>
setter方法注入
< bean id=”userService” class=”com.mummy.spring.service.UserService”>
< property name=”userDao” ref=”userDao”/>
< /bean>
setter方法注入的注意点,property中的name必须和依赖类中的set方法的后半部分相似,例如:setName() 则propery中的name则是name;setUid 则propery中的name则是uid;
好的编程风格应该是set后的成员变量名首字母大写,则property中的name直接比对成员变量的名称即可.成员变量正规的讲,应该是实例域

Spring针对于bean,他可以被指定为是延迟加载的

延迟加载是啥呢?

I:Spring是默认在容器启动时,就加载配置文件中被注册好的bean类的.(一启动容器,就创建好所有被注册的类的对象)
II:而延迟加载呢,是当容器启动的时候不去创建类的实例,等到需要被创建的时候才去创建.
III:这样做的优点就是节省内存资源(貌似现在内存也不贵了,哈哈哈)
IV:应用场景:当你的依赖类A在创建实例之前需要依赖于被依赖类B的实例,此时这个A就需要延迟加载,需要等B先实例化一个实例.

Spring针对bean属性scope,可以被指定为是singleton(单例)还是prototype(原型)

singleton是啥呢?

I:知道月亮吧,有且仅有一个,简略了解一下,下一篇单独讲一讲单例模式吧!
II:原型:相当于皇帝的老婆,千千万,各有各的特色.
由bean创建出来的实例都是同一个,怎么比较呢?
对象的相等性有两种方式:==和equals方法比较,==是会比较对象在内存中的hash值的,而equals则不会,只比较对象是否是同类型!

< bean id=”userDao” class=”com.mummy.spring.dao.UserDao” scope=”prototype”>< / bean >
bean默认是单例创建的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值