IOC核心概念

Ioc和DI

Ioc(Inversion of Contorl)控制反转---->一种编程思想

为了降低程序的耦合性,我们由主动new一个对象转换为由外部提供对象。

此过程中对象创建控制权由程序转移到外部,这种思想叫做控制反转。

Spring技术对这种思想进行了实现。

Spring提供了一个容器,称之为“Ioc容器”充当Ioc思想中的外部。

Ioc容器负责对象的创建、初始化等一系列操作,被创建或者管理的容器在Ioc容器中成为bean。

DI(dependency Injection)依赖注入

在容器中建立bean与bean之间的依赖关系的整个过程,称之为依赖注入。

Ioc入门

1、导入maven坐标

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>

2、创建Spring配置文件

    bean标签表示配置bean
    id属性表示给bean起名字
    class属性表示给bean定义类型

注意:之前的new我们可以理解为自己做菜,而这里面的bean相当于告诉计算机菜单,要求计算机给你做哪些菜。同时对于bean,我们可以在不同的bean中间建立起联系。

<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">
    <!--1、导入Spring对应的依赖坐标-->

    <!--2、配置bean-->

    <bean id="BookDao" class="com.tsj.dao.impl.BookDaoImpl"/>

    <bean id="BookService" class="com.tsj.service.impl.BookServiceImpl"/>

</beans>

3、获取Ioc容器

4、通过Ioc容器获取bean 

public class APP2 {
    public static void main(String[] args) {
        //3、获取Ioc容器
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");

        //4、获取bean
        //此处利用了接口多态,即编辑看左,运行看右边,创建的对象实际是实现类对象,但是类型是接口(向上转换)
        BookDao BookDao=(BookDao) act.getBean("BookDao_test");
        //调用了子类中重写的方法,且向上转换只能调用子类重写的方法
        BookDao.save();
    }
}

DI入门(基于Ioc管理bean) 

为了将service中通过new创建dao对象的代码删除,我们需要提供在service中创建dao对象的方法。同时,我们需要在配置文件中描述service对象和dao对象之间的关系。

5、去除new

6、创建set方法提供dao对象

public class BookServiceImpl implements BookService {
    //5、去除new
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("BookServiceImpl is saving");
        bookDao.save();
    }

    //6.提供对应的set方法
    //set方法是容器在调用,谁要创建对象谁调用
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

7、配置sever与dao的关系 

请注意:第一个name对应的bookDao指的是方法形参,用来对应创建对象。

                第二个ref对应的bookDao指的是关联其他bean的id,(其实关联其他bean的name别名也可以起到同样的效果,但是我们一般不这样使用)。

    <bean id="bookService" name="service" class="com.tsj.service.impl.BookServiceImpl" scope="prototype">
        <property name="bookDao" ref="bookDao"/>
    </bean>

bean详解

1、bean的基础配置

格式:<beans>

<bean></bean>

</beans>

属性:id:容器根据id获取对应的bean,一个容器id值唯一

        class:bean的类型,即配置bean的全路径类名

2、bean的作用范围

名称:scope

功能:控制bean创建的对象是否单例(多次创建是否是同一个对象)

singleton:单列

prototypr:非单列

<bean id="BookService" class="com.tsj.service.impl.BookServiceImpl" scope="prototype"/>

为什么Spring创建的对象大多都是单列的?

这是因为Spring所创建的bean主要是复用的对象,即拿一次用一次,这样才会更加节省资源。 

3、bean的同名配置

名称:name

功能:定义bean的别名,可以有多个,可以用逗号,分号,空格隔开。

<bean id="BookDao" name="BookDao_test" class="com.tsj.dao.impl.BookDaoImpl"/>

bean实列化的三种方法

bean的本质:bean是一个对象,创建对象通过无参数的构造方法创建。

方法一:通过可访问的无参数构造方法在实现类中创建对象

其实写不写构造方法是一样的,如果你不写虚拟机会自动提供。

无参构造方法如果不存在,将会抛出BeanCreationException。

   //创建构造方法
    public BookDaoImpl(){
        System.out.println("book dao constructor is running");
    }

方法二:静态工厂创建对象

创建工厂返回对象,可以提前做出一些配置,比如说sout

public class OrderDaoFactory {
    //通过类名调用静态方法
    public static OrderDao getOrderDao(){
        System.out.println("factory is setting up");
        //通过工厂返回方法创建一个对象
        return new OrderDaoImpl();
    }
}

配置文件 

 <!--方法二:使用静态工厂实例化bean-->
    <!--因为我们想要调用工厂的方法返回对象,所以我们需要设置factory-method-->
    <bean id="orderDao" class="com.tsj.dao.factory.OrderDaoFactory" factory-method="getOrderDao"/>

主页app

public class APP {
    public static void main(String[] args) {
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");

        //5、获取bean
        //此处利用了接口多态,即编辑看左,运行看右边,创建的对象实际是实现类对象,但是类型是接口(向上转换)
        OrderDao OrderDao=(OrderDao) act.getBean("orderDao");
        //调用了子类中重写的方法,且向上转换只能调用子类重写的方法
        OrderDao.save();
    }
}

方法三:非静态工厂创建对象

public class UserFactory {
    public  UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

第一行的UserFactory实际上并没有意义,仅仅作为第二个bean的变量存在。

第二个bean中的方法名每次都不固定,所以这种方法并不实用。

    <bean id="UserFactory" class="com.tsj.dao.factory.UserFactory" />
    <bean id="UerDao" factory-method="getUserDao" factory-bean="UserFactory"/>

方法四:方法三的改良

public class UserFactoryBean implements FactoryBean<UserDao> {
    //代替原始实列中创建对象的方法
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    //对象的返回值是什么类型
    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
     //是否为单列对象
    @Override
    public boolean isSingleton(){
       return true;
    }
}

这里的对象造出的不是FactoryBean的对象,这里造出来的是Object对象。 

  <bean id="userdao" class="com.tsj.dao.factory.UserFactoryBean"/>

创建对象页面 

    public static void main(String[] args) {
        UserFactoryBean userFactoryBean = new UserFactoryBean();
        try {
            UserDao object = userFactoryBean.getObject();
            object.save();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

管理第三方bean(案例)

 

Bean的生命周期

生命周期:从创建到销毁的完整过程

bean生命周期:bean从创建到销毁的整体过程

bean生命周期控制:bean创建后到销毁前做的一些事情

初始化容器

1、创建对象(内存分配)

2、执行构造方法

3、执行属性注入(set操作)

4、执行bean初始化方法

使用bean

1、执行业务操作

关闭/销毁容器

1、执行bean销毁方法

2、注意:一般情况下虚拟机运行结束会自动关闭,来不及执行销毁方法,我们可以手动关闭容器。

方法一:

将Ioc容器对象改变成其子类,以调用子类方法

ClassPathXmlApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");

act.close();

方法二:

关闭流

ClassPathXmlApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");

act.registerShutdownHook();

bean生命周期的两种控制方法

方法一:通过提供方法,并且在配置文件中配置

 //表示bean初始化的操作
   public void init(){
       System.out.println("init...");
   }
   //表示bean销毁前的操作
    public void destroy(){
        System.out.println("destory....");
    }
<bean id="bookDao" name="BookDao_test" class="com.tsj.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

方法二:通过实现接口的方式

实现InitializingBean, DisposableBean这两个接口

public class BookServiceImpl implements BookService , InitializingBean, DisposableBean {
    //5、去除new
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("BookServiceImpl is saving");
        bookDao.save();
    }

    //6.提供对应的set方法
    //set方法是容器在调用,谁要创建对象谁调用
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("service destory");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值