1.创建bean类,并在spring中进行配置交由spring来管理1. IOC(DI) - 控制反转(依赖注入)
    所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周期的管理,而是在需要时由Spring框架提供,这个由spring框架管理对象创建和生命周期的机制称之为控制反转。而在 创建对象的过程中Spring可以依据配置对对象的属性进行设置,这个过称之为依赖注入,也即DI。
    
2. IOC的入门案例
    a. 下载Spring
        访问Spring官网,下载Spring相关的包
    b. 解压下载好的压缩包
        其中包含着Spring的依赖包
    c. 创建一个java项目
        spring并不是非要在javaweb环境下才可以使用,一个普通的java程序中也可以使用Spring。
 d.导入Spring的libs目录下IOC相关的jar包

  

e. 创建Spring的配置文件
  Spring采用xml文件作为配置文件,xml文件名字任意,但通常都取名为applicationContext.xml,通常将该文件放置在类加载的目录里下  (src目录),方便后续使用。

  f.创建bean类,并在spring中进行配置交由spring来管理

                 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
        
        <bean id="person" class="cn.tedu.beans.Person"></bean>
        
</beans>

g. 在程序中通过Spring容器获取对象并使用

         1   public class Person_Test {
2 @Test
3 /**
4 * SpringIOC的入门案例
5 */
6 public void test1(){
7 ApplicationContext context =
8 new ClassPathXmlApplicationContext("applicationContext.xml");
9 Person p = (Person) context.getBean("person");
10 p.say();
11 }
12 }

3. IOC的实现原理
    在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的<bean>标签时,会根据该标签中的class属性指定的类的全路径名,通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。
    之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。
    
    由此可以推测而知:
        默认情况下,多次获取同一个id的bean,得到的将是同一个对象。
        即使 是同一个类,如果配置过多个<bean>标签具有不同的id,每个id都会在内置Map中有一个键值对,其中的值是这个类创建的不同的对象
        同一个<beans>标签下不允许配置多个同id的<bean>标签,如果配置则启动抛异常
    
4. IOC获取对象的方式
    通过context.getBeans()方法获取bean时,可以通过如下两种方式获取:
        传入id值
        传入class类型
    通过class方式获取bean时,如果同一个类配置过多个bean,则在获取时因为无法确定到底要获取哪个bean会抛出异常。
    而id是唯一的,不存在这样的问题,所以建议大家尽量使用id获取bean。

        1     @Test
2 /**
3 * SpringIOC获取bean的方式
4 */
5 public void test3(){
6 /*
7 <bean id="person" class="cn.tedu.beans.Person"></bean>
8 */
9 /*
10 <bean id="person" class="cn.tedu.beans.Person"></bean>
11 <bean id="personx" class="cn.tedu.beans.Person"></bean>
12 */
13 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
14 //--通过id获取
15 Person p1 = (Person) context.getBean("person");
16 p1.say();
17 //--通过class获取
18 Person p2 = context.getBean(Person.class);
19 p2.say();
20 }

5. 别名标签
    在 Spring中提供了别名标签<alias>可以为配置的<bean>起一个别名,要注意的是这仅仅是对指定的<bean>起的一个额外的名字,并不会额外的创建对象存入map。
        <alias name="要起别名的bean的id"  alias="要指定的别名"/>

        1     @Test
2 /**
3 * SpringIOC中bean别名
4 */
5 public void test4(){
6 /*
7 <bean id="person" class="cn.tedu.beans.Person"></bean>
8 <alias name="person" alias="personx"/>
9 */
10 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
11 //--通过id获取
12 Person p1 = (Person) context.getBean("personx");
13 p1.say();
14 }

6. Spring创建对象的方式
    a. 通过类的无法构造方法创建对象
        在入门案例中使用的就是这种方式。当用最普通方式配置一个<bean>时,默认就是采用类的无参构造创建对象。在Spring容器初始化时,通过<bean>上配置的class属性反射得到字节码对象,通过newInstance()创建对象

                1     Class c = Class .forName("类的全路径名称")
2 Object obj = c.newInstance()
这种方式下spring创建对象,要求类必须有无参的构造,否则无法通过反射创建对象,会抛出异常。
1 package cn.tedu.beans;
2
3 public class Person {
4 public Person(String arg) {
5 System.out.println("Person的无参构造执行了。。。");
6 }
7 public void say(){
8 System.out.println("person hello spring~");
9 }
10 }
11 @Test
12 /**
13 * SpringIOC 创建对象方式 1 - 通过无参构造方法创建对象
14 */
15 public void test5(){
16 /*
17 <bean id="person" class="cn.tedu.beans.Person"></bean>
18 */
19 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
20 Person p = (Person) context.getBean("person");
21 p.say();
22 }

b. 通过静态工厂创建对象
        很多的时候,我们面对的类是无法通过无参构造去创建的,例如该类没有无参构造、是一抽象类 等等情况 ,此时无法要求spring通过无参构造创建对象,此时可以使用静态工厂 方式创建对象。

            1     public class CalendarStaticFactory {
2 public static Calendar getCalendar(){
3 return Calendar.getInstance();
4 }
5 }
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
6
7 <bean id="calendar" class="cn.tedu.factory.CalendarStaticFactory" factory-method="getCalendar"></bean>
8
9 </beans>
1 @Test
2 /**
3 * SpringIOC 创建对象方式 2 - 静态工厂
4 */
5 public void test6(){
6 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7 Calendar calendar = (Calendar) context.getBean("calendar");
8 System.out.println(calendar);
9 }

c. 实例工厂创建对象
        实例工厂也可以解决类是无法通过无参构造创建的问题,解决的思路和静态 工厂类似,只不过实例工厂提供的方法不是静态的。spring需要先创建出实例工厂的对象,在调用实例工厂对象上指定的普通方法来创建对象。所以实例工厂也需要配置到Spring中管理。

            1     package cn.tedu.factory;
2
3 import java.util.Calendar;
4
5 public class CalendarFactory {
6 public Calendar getCalendar(){
7 return Calendar.getInstance();
8 }
9 }
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
6
7 <bean id="calendarFactory" class="cn.tedu.factory.CalendarFactory"></bean>
8 <bean id="calendar" factory-bean="calendarFactory" factory-method="getCalendar"/>
9
10 </beans>
1 @Test
2 /**
3 * SpringIOC 创建对象方式 3 - 实例工厂
4 */
5 public void test7(){
6 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7 Calendar calendar = (Calendar) context.getBean("calendar");
8 System.out.println(calendar);
9 }

d. Spring工厂创建对象
        Spring内置了工厂接口,也可以通过实现这个接口来开发Spring工厂,通过这个工厂创建对象。

            1     package cn.tedu.factory;
2
3 import java.util.Calendar;
4
5 import org.springframework.beans.factory.FactoryBean;
6
7 public class CalendarSpringFactory implements FactoryBean<Calendar>{
8
9 /**
10 * Spring工厂生产对象的方法
11 */
12 @Override
13 public Calendar getObject() throws Exception {
14 return Calendar.getInstance();
15 }
16
17 /**
18 * 获取当前工厂生产的对象的类型的方法
19 */
20 @Override
21 public Class<?> getObjectType() {
22 return Calendar.class;
23 }
24
25 /**
26 * Spring工厂生产对象时是否采用单例模式
27 * 如果返回true,则在spring中该对象只创建一次 后续 重复使用
28 * 如果返回false,则每次获取该bean 都重新 创建对象
29 */
30 @Override
31 public boolean isSingleton() {
32 return true;
33 }
34
35 }
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
6
7 <bean id="calendar" class="cn.tedu.factory.CalendarSpringFactory"></bean>
8
9 </beans>
1 @Test
2 /**
3 * SpringIOC 创建对象方式 3 - spring工厂
4 */
5 public void test8(){
6 /*
7 <bean id="calendar" class="cn.tedu.factory.CalendarSpringFactory"></bean>
8 */
9 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
10 Calendar calendar = (Calendar) context.getBean("calendar");
11 System.out.println(calendar);
12 }

7. 单例和多例
    Spring容器管理的bean在默认情况下是单例的,也即,一个bean只会创建一个对象,存在内置 map中,之后无论获取多少次该bean,都返回同一个对象。
    
    Spring默认采用单例方式,减少了对象的创建,从而减少了内存的消耗。
    但是在实际开发中是存在多例的需求的,Spring也提供了选项可以将bean设置为多例模式。

         1     <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
6
7 <!--
8 scope属性控制当前bean的创建模式:
9 singleton:则当前bean处在单例模式中,默认就是此模式
10 prototype:则当前bean处在多例模式中
11 -->
12 <bean id="cart" class="cn.tedu.beans.Cart" scope="prototype"></bean>
13
14 </beans>

bean在单例模式下的生命周期:
        bean在单例模式下,spring容器启动时解析xml发现该bean标签后,直接创建该bean的对象存入内部map中保存,此后无论调用多少次getBean()获取该bean都是从map中获取该对象返回,一直是一个对象。此对象一直被Spring容器持有,直到容器退出时,随着容器的退出对象被销毁。
    
    bean在多例模式下的生命周期:
        bean在多例模式下,spring容器启动时解析xml发现该bean标签后,只是将该bean进行管理,并不会创建对象,此后每次使用 getBean()获取该bean时,spring都会重新创建该对象返回,每次都是一个新的对象。这个对象spring容器并不会持有,什么销毁取决于使用该对象的用户自己什么时候销毁该对象。
    
        实验:通过断点调试模式 ,观察spring单例和多例的bean执行构造的过程
                1     略

8. 懒加载机制
    Spring默认会在容器初始化的过程中,解析xml,并将单例的bean创建并保存到map中,这样的机制在bean比较少时问题不大,但一旦bean非常多时,spring需要在启动的过程中花费大量的时间来创建bean 花费大量的空间存储bean,但这些bean可能很久都用不上,这种在启动时在时间和空间上的浪费显得非常的不值得。
    所以Spring提供了懒加载机制。所谓的懒加载机制就是可以规定指定的bean不在启动时立即创建,而是在后续第一次用到时才创建,从而减轻在启动过程中对时间和内存的消耗。
    懒加载机制只对单例bean有作用,对于多例bean设置懒加载没有意义。
    
    懒加载的配置方式:
        为指定bean配置懒加载

                1     <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
6 >
7
8 <bean id="cart" class="cn.tedu.beans.Cart" lazy-init="true"></bean>
9
10 </beans>
为全局配置懒加载
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
6 default-lazy-init="true"
7 >
8
9 <bean id="cart" class="cn.tedu.beans.Cart"></bean>
10
11 </beans>

**如果同时设定全局和指定bean的懒加载机制,且配置不相同,则对于该bean局部配置覆盖全局配置。
    
        实验:通过断点调试,验证懒加载机制的执行过程

    1     package cn.tedu.beans;
2
3 public class Cart {
4 public Cart() {
5 System.out.println("Cart init...");
6 }
7 }
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
6 >
7
8 <bean id="cart" class="cn.tedu.beans.Cart" lazy-init="true"></bean>
9
10 </beans>
1 @Test
2 /**
3 * SpringIOC 懒加载机制
4 */
5 public void test10(){
6 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7 Cart cart1 = (Cart) context.getBean("cart");
8 Cart cart2 = (Cart) context.getBean("cart");
9 System.out.println(cart1 == cart2);
10 }

9. 配置初始化和销毁的方法
    在Spring中如果某个bean在初始化之后 或 销毁之前要做一些 额外操作可以为该bean配置初始化和销毁的方法 ,在这些方法中完成要功能。
    
        实验:通过断点调试模式,测试初始化方法 和 销毁方法的执行

     1     package cn.tedu.beans;
2
3 public class ProdDao {
4
5 public ProdDao() {
6 System.out.println("ProdDao 被创建。。。");
7 }
8
9 public void init(){
10 System.out.println("init。。连接数据库。。。。。");
11 }
12
13
14 public void destory(){
15 System.out.println("destory。。断开数据库。。。。。");
16 }
17
18 public void addProd(){
19 System.out.println("增加商品。。");
20 }
21 public void updateProd(){
22 System.out.println("修改商品。。");
23 }
24 public void delProd(){
25 System.out.println("删除商品。。");
26 }
27 public void queryProd(){
28 System.out.println("查询商品。。");
29 }
30 }
         1     <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
6 >
7
8 <bean id="prodDao" class="cn.tedu.beans.ProdDao"
9 init-method="init" destroy-method="d y"></bean>
10
11 </beans>
1 @Test
2 /**
3 * SpringIOC 初始化和 销毁方法
4 */
5 public void test11(){
6 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7 ProdDao prodDao = (ProdDao) context.getBean("prodDao");
8 prodDao.addProd();
9 context.close();
10 }

    **Spring中关键方法的执行顺序:
        在Spring创建bean对象时,先创建对象(通过无参构造或工厂),之后立即调用init方法来执行初始化操作,之后此bean就可以哪来调用其它普通方法,而在对象销毁之前,spring容器调用其destory方法来执行销毁操作。

Spring知识点总结(二)之Spring IOC的更多相关文章

  1. Spring Boot 2 (二):Spring Boot 2 动态 Banner

    Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...

  2. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  3. Spring知识点小结(二)

    一.配置非自定义的Bean(数据源DataSource模型) DBCP数据源:        导入dbcp的jar包:dbcp+pool+connector                代码实现:  ...

  4. Spring学习(二)--Spring的IOC

    1.依赖反转模式 依赖反转:高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象接口.抽象接口不应该依赖于具体实现.而具体实现则应该依赖于抽象接口. 在面向对象编程领域中,依赖反转原则(Depe ...

  5. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  6. Spring学习(二)——Spring中的AOP的初步理解

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  7. Spring实战(二)Spring容器和bean的生命周期

    引入问题: 在XML配置文件中配置bean后,这些文件又是如何被加载的?它们被加载到哪里去了? Spring容器——框架核心 1.什么是Spring容器?它的功能是什么? 在基于Spring的应用中, ...

  8. Spring学习(二)Spring IoC 和 DI 简介

    一.IOC(控制反转) 定义:反转控制 (Inversion Of Control)的缩写,即创建对象的反转控制. 正向控制:若要使用某个对象,需要自己去负责对象的创建. 反向控制:若要使用某个对象, ...

  9. Spring(十二):IOC容器中Bean的生命周期方法

    IOC容器中Bean的生命周期方法 1)Spring IOC容器可以管理Bean的声明周期,Spring允许在Bean生命周期的特定点执行定制的任务. 2)Spring IOC容器对Bean的生命周期 ...

随机推荐

  1. NBUT 1107——盒子游戏——————【博弈类】

    盒子游戏 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format: Submit Status Practice NBUT 110 ...

  2. 跨域策略文件crossdomain.xml文件

    使用crossdomain.xml让Flash可以跨域传输数据 一.crossdomain.xml文件的作用    跨域,顾名思义就是需要的资源不在自己的域服务器上,需要访问其他域服务器.跨域策略文件 ...

  3. 项目管理系统 TAIGA 部署

    题记 使用了 MantisBT 一段时间,觉得功能太少,只局限在错误跟踪,而且操作体验比较差,界面很糟糕,很早就想将其换掉. 偶然发现一个很不错的新选择:Taiga,于是就试着将其部署下来,发现绝对是 ...

  4. 移动端下滑刷新插件(jQuery插件)

    由于在工作不能独自开发,而且为了给他们方便,自己写过不少的插件,不过今天刚好空闲,发出刚好完成的,移动端的下滑到底刷新插件.我不是很喜欢写插件给别人用,因为用起来自然是简单的,没什么难度,所以一起分享 ...

  5. 跨源资源共享(CORS)

    一.跨源的定义一个“源”有三部分组成:协议.域名.端口.任一部分不一致即为跨源.比如:(http,example.com,80)和(https,example.com,443)就是不同的源.   二. ...

  6. PAT 1076 Forwards on Weibo

    #include <cstdio> #include <cstdlib> #include <vector> #include <queue> #inc ...

  7. BZOJ2438: [中山市选2011]杀人游戏(tarjan)

    题意 题目链接 Sol 这题挺考验阅读理解能力的.. 如果能读懂的话,不难发现这就是在统计有多少入度为\(0\)的点 缩点后判断一下即可 当然有一种例外情况是\(1 -> 3, 2 -> ...

  8. Android仿QQ界面

    最近这几天,一直跟着朋友们聚会什么的,没怎么做项目,今天总算是有时间开电脑继续做我的项目了.下面我就把我做的效果展示一下. 这是模仿了qq的界面效果.因为代码比较长就不粘贴代码了.需要的小伙伴可以跟我 ...

  9. Centos6安装oracle10g

    刚刚开始学OCP.第一关,安装,被折腾得稀碎...查询了大量资料,多次失败后终于总结出一些经验,简单整理如下.[2014-12-11 重新整理了一下顺序,修改了脚本!] 需要注意的是:如果想尝试我提供 ...

  10. Oracle运行依赖的服务

    1.Oracle ORCL VSS Writer Service. Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Service)能够让存储基础设备(比如磁盘,阵列等) ...