Spring学习笔记二

什么是IOC

IOC,Inversion of Control,控制反转。是一种设计思想。
传统的创建对象的方法是直接通过new关键字,而Spring则是通过IOC容器来创建对象的,也就是将创建对象的控制权交给了IOC容器。
一句话:IOC让程序员不住关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建、初始化、销毁等工作交给了Spring容器

Spring 容器创建对象的三种方式

第一步:创建项目,导入maven依赖,如下图:
在这里插入图片描述
第二步:创建测试对象 HelloIoc

public class HelloIoc{
    public void sayHello(){
        System.out.println("Hello IOC");
    }
}

传统方法创建对象

public class App {
    public static void main( String[] args ){
        HelloIoc helloIoc = new HelloIoc();
        helloIoc.sayHello();
    }
}

通过Spring容器来创建:

第一种方法:利用默认构造方法
在src目录下新建applicationContext.xml文件,这是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.xsd">
    <!--
    创建对象的第一种方式:利用无参构造器
    id:唯一标识符
    class:类的全类名
      -->
    <bean id="helloIoc" class="com.rzjt.ioc.HelloIoc" ></bean>  
    <!-- 别名属性  name:和bean的 id 属性对应 -->
    <alias name="helloIoc" alias="helloIoc2"/>
     
</beans>

测试

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //从 spring 容器获取对象
        HelloIoc helloIoc = (HelloIoc) context.getBean("helloIoc");
        helloIoc.sayHello();

        //利用配置文件 alias 别名属性创建对象
        HelloIoc helloIoc2 = (HelloIoc) context.getBean("helloIoc2");
        helloIoc2.sayHello();

        context.close();
    }
}

在类HelloIoc中手动添加无参的构造方法,然后执行上面的测试代码,会发现构造方法会在sayHello方法前调用

第二种方法:利用静态工厂方法

创建静态工厂类:

public class HelloStaticFactory{

    public HelloStaticFactory(){
        System.out.println("Hellostaticfactory");
    }

    //静态工厂方法
    public static HelloIoc getInstance(){
        return new HelloIoc();
    }
}

在applicationContext.xml中配置

<!--
    创建对象的第二种方式:利用静态工厂方法
    factory-method:静态工厂类的获取对象的静态方法
    class:静态工厂类的全类名
  -->   
<bean id="helloStaticFactory" factory-method="getInstances" class="com.rzjt.ioc.HelloStaticFactory"></bean>

测试

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        HelloIoc staticFactory = (HelloIoc) context.getBean("helloStaticFactory");
        staticFactory.sayHello();

        context.close();
    }
}

spring只负责调用静态工厂方法,这个静态方法内部实现由程序员完成

第三种方法:利用实例工厂方法

创建实例工厂类HelloInstanceFactory

public class HelloInstanceFactory{
    public HelloInstanceFactory(){
        System.out.println("实例工厂构造方法");
    }

    //实例工厂方法创建对象
    public HelloIoc getInstance(){
        return new HelloIoc();
    }
}

在applicationContext.xml中进行配置:

<!--
    创建对象的第三种方式:利用实例工厂方法
    factory-bean:指定当前Spring中包含工厂方法的beanID
    factory-method:工厂方法名称
  --> 
<bean id="instanceFactory" class="com.rzjt.ioc.HelloInstanceFactory"></bean> 
<bean id="instance" factory-bean="instanceFactory" factory-method="getInstance"></bean> 

测试

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        HelloIoc instanceFactory = (HelloIoc) context.getBean("instance");
        instanceFactory.sayHello();

        context.close();
    }
}

Spring 容器创建对象的时机

第一种:默认情况下,启动spring容器就创建对象(遇到bean便创建对象)

在HelloIoc中添加默认构造方法:

public class HelloIoc{

    //默认无参构造方法
    public HelloIoc(){
        System.out.println("HelloIoc default constructor");
    }
    public void sayHello(){
        System.out.println("Hello IOC");
    }
}

在applicationContext.xml 中添加 bean,现在里面有三个bean了

启动容器测试

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //从 spring 容器获取对象
        HelloIoc helloIoc = (HelloIoc) context.getBean("helloIoc");
        helloIoc.sayHello();

        //利用配置文件 alias 别名属性创建对象
        HelloIoc helloIoc2 = (HelloIoc) context.getBean("helloIoc2");
        helloIoc2.sayHello();

        HelloIoc staticFactory = (HelloIoc) context.getBean("helloStaticFactory");
        staticFactory.sayHello();

        HelloIoc instanceFactory = (HelloIoc) context.getBean("instance");
        instanceFactory.sayHello();

        context.close();
    }
}

看到结果

HelloIoc default constructor
HelloIoc default constructor
实例工厂构造方法
HelloIoc default constructor
Hello IOC
Hello IOC
Hello IOC
Hello IOC

第二种:在spring的配置文件bean中有一个属性lazy-init="default/true/false"

  1. 如果lazy-init为default 或 false 在启动spring容器时创建对象(默认情况)
  2. 如果lazy-init为true时 在context.getBean时才创建对象

修改applicationContext.xml

<!--
    创建对象的第一种方式:利用无参构造器
    id:唯一标识符
    class:类的全类名
  -->
<bean id="helloIoc" class="com.rzjt.ioc.HelloIoc" lazy-init = "true" ></bean>  

执行结果变为了

HelloIoc default constructor
实例工厂构造方法
HelloIoc default constructor
HelloIoc default constructor
Hello IOC
Hello IOC
Hello IOC
Hello IOC

在第一种情况下可以在启动spring容器时,检查spring容器配置文件的正确性,但是这样的缺点是把一些bean过早的放在了内存中,如果数据量大,堆内存是消耗
第二种情况下,可以减少内存的消耗,但是不容易发现错误

Spring的bean中的作用域scope

分为singleton、prototype、request、session、global session

默认scope的值是singleton,产生的对象是单例的

在applicatonContext.xml配置:

<!--
    创建对象的第一种方式:利用无参构造器
    id:唯一标识符
    class:类的全类名
  -->
<bean id="helloIoc" class="com.rzjt.ioc.HelloIoc" scope = "singleton"></bean>  

验证

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        HelloIoc helloIoc1 = (HelloIoc) context.getBean("helloIoc");
        HelloIoc helloIoc2 = (HelloIoc) context.getBean("helloIoc");
        System.out.println(helloIoc1.equals(helloIoc2)); // true

        context.close();
    }
}

scope = "prototype"多例模式,并且spring容器启动的时候并不会创建对象,而是在得到 bean 的时候才会创建对象

在applicatonContext.xml配置:

<!--
    创建对象的第一种方式:利用无参构造器
    id:唯一标识符
    class:类的全类名
  -->
<bean id="helloIoc" class="com.rzjt.ioc.HelloIoc" scope = "prototype"></bean>  

验证

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        HelloIoc helloIoc1 = (HelloIoc) context.getBean("helloIoc");
        HelloIoc helloIoc2 = (HelloIoc) context.getBean("helloIoc");
        System.out.println(helloIoc1.equals(helloIoc2)); // false

        context.close();
    }
}

总结:在单例模式下,启动spring容器,便会创建对象;在多例模式下,启动容器并不会创建对象,获得bean的时候才会创建对象

Spring 容器生命周期

创建SpringLifeCycle.java

public class SpringLifeCycle{

    public  SpringLifeCycle(){
        System.out.println("SpringLifeCycle");
    }

    public void init(){
        System.out.println("init...");
    }

    public void destroy(){
        System.out.println("destroy...");
    }

    public void sayHello(){
        System.out.println("say Hello...");
    }
}

applicationContext.xml

<!-- 生命周期 -->
<bean id="springLifeCycle" class="com.rzjt.ioc.SpringLifeCycle" init-method="init" destroy-method="destroy"></bean>

测试:

public class App {
    public static void main( String[] args ){

        //启动 spring 容器
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        SpringLifeCycle hello = (SpringLifeCycle) context.getBean("springLifeCycle");
        hello.sayHello();

        context.close();
    }
}

打印

SpringLifeCycle
init...
say Hello...
destroy...

总结:spring容器的声明周期

  1. spring容器创建对象
  2. 执行init方法
  3. 调用自己的方法
  4. 当spring容器关闭的时候执行destroy方法

注意:当scope为“prototype”时,调用close方法时是不会调用destroy方法的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值