认识Spring与bean的操作

认识Spring

  • Spring官网:https://spring.io/

  • spring Framework是Spring生态圈中最基础的项目,是其他项目的根基

  • Spring Frame系统架构图

在这里插入图片描述

核心概念(理解)

当前代码现状:耦合度高

例子:

业务层:

public class BookServiceImpl implements BoosService{
    private BookDao bookDao;
    public void save(){
        bookDao.save();
    }
}

数据层实现:

public class BookDaoImpl implements BookDao{
    public void save(){
        System.out.println("book dao save ...");
    }
}
public class BookDao Impl2 implements BookDao{
    public void save(){
        System.out.println("book dao save ... 2");
    }
}

为了解决这个问题,在程序中不要主动new产生对象,转换为由外部提供对象

所以提出了Ioc(Inversion of Control)控制反转思想

Ioc

控制反转:对象的创建控制权由程序转移到外部,这种思想被称之为控制反转

spring技术对Ioc思想进行了实现:

  • Spring提供了一个容器,成为Ioc容器,用来充当Ioc思想中的“外部”
  • Ioc容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean

DI

DI(Dependency Injection)依赖注入

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

Ioc入门案例

项目准备:

1.创建一个maven项目

2.创建包结构:

在这里插入图片描述

3.文件:

BookDaoImpl.java

package com.itheima.dao.impl;

import com.itheima.dao.BookDao;

public class BookDaoImpl implements BookDao {
    public void save(){
        System.out.println("book dao save ... ");
    }

}

BookDao.java

package com.itheima.dao;

public interface BookDao {
    void save();
}

BookServiceImpl.java

package com.itheima.service.Impl;

import com.itheima.dao.BookDao;
import com.itheima.dao.impl.BookDaoImpl;
import com.itheima.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

BookService.java

package com.itheima.service;

public interface BookService {
    void save();
}

App.java

package com.itheima;

import com.itheima.service.BookService;
import com.itheima.service.Impl.BookServiceImpl;

public class App {
    public static void main(String[] args) {
        BookService bookService = new BookServiceImpl();
        bookService.save();
    }
}

愉快的开始

1.在pom.xml导入spring坐标,刷新一下maven
 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.21</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
2.定义Spring的管理类(接口),在准备阶段已经完成
3.鼠标右键resources文件夹,创建一个Spring配置:applicationContext.xml,注意要完成导入坐标才可以创建

在这里插入图片描述

application.xml

<?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">

    <!--    1.导入Spring的坐标:spring-context,对应版本是5.3.21-->

    <!--    2.配置bean-->
    <!--    注意这里要配实现类,不要配接口-->
    <!--    id属性表示给bean起名字-->
    <!--    class属性表示给bean定义类型-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="com.itheima.service.Impl.BookServiceImpl"/>

</beans>
  • 注:bean定义时id属性在同一个上下文中不能重复
4.初始化Ioc容器(Spring核心容器/Spring容器),通过容器获取bean

App2.java

package com.itheima;

import com.itheima.dao.BookDao;
import com.itheima.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

        //4.获取bean
//        BookDao bookDao = (BookDao)ctx.getBean("bookDao");
//        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();


    }
}

DI入门案例(XML版本)

1.删除使用new形式创建的代码
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao ;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

    //6.提供对应的set方法
    public void setBookDao(BookDao bookDao){
        this.bookDao=bookDao;
    }
2.提供依赖对象对应的setter方法
3.配置service与dao之间的关系
<?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">

    <!--    1.导入Spring的坐标:spring-context,对应版本是5.3.21-->

    <!--    2.配置bean-->
    <!--    注意这里要配实现类,不要配接口-->
    <!--    id属性表示给bean起名字-->
    <!--    class属性表示给bean定义类型-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="com.itheima.service.Impl.BookServiceImpl">

        <!--        7.配置service与dao的关系-->
        <!--        property表示关联的属性-->
        <!--        name表示的是service实现类里面的属性对象-->
        <!--        ref表示的是配置文件里的bean的id-->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

bean基础配置

bean
类别描述
名称bean
类型标签
所属beans标签
功能定义Spring核心容器所管理的对象
格式
属性列表id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一 class:bean的类型,即配置的bean的全路径类名
范例
name
类别描述
名称name
类型属性
所属bean标签
功能定义bean的别名,可定义多个,使用逗号(,)分号(;)或者空格( )分割
范例
    <bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"/>

    <!--    name表示别名,多个别名之间用空格隔开-->
    <bean id="bookService" name="service service2 bookEbi" class="com.itheima.service.Impl.BookServiceImpl">
        <!--        这里的ref可以使用别名了-->
        <property name="bookDao" ref="bookDao"/>
    </bean>
  • 注:获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException``NoSuchBeanDefinitionException:No bean named 'bookServiceImpl' available
scope
类别描述
名称scope
类型属性
所属bean标签
功能定义bean的作用范围,可选范围如下:①singleton:单例(默认)②protortype:非单例
范例
  • bean默认为单例,适合交给容器管理的bean一般不可改变
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  • 不适合交给容器进行管理的bean:有状态的对象
    • 封装实体的域对象

bean实例化

  • 查看IDEA报错的方法:

从最底部的错误原因逐层往上找

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

最终会发现这个是没有无参构造函数导致的错误

构造方法(常用)
  • 提供可访问的构造方法
public class BookDaoImpl implements BookDao {

    //    提供无参构造
    public BookDaoImpl() {
        System.out.println("book dao constructor is running ...");
    }

    public void save() {
        System.out.println("book dao save ... ");
    }

}
  • 配置
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
  • 如果无参构造方法不存在,将抛出异常BeanCreationException
静态工厂(了解)
  • 静态工厂
package com.itheima.factory;

import com.itheima.dao.OrderDao;
import com.itheima.dao.impl.OrderDaoImpl;

public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        System.out.println("factory setup ......");
        return new OrderDaoImpl();
    }
}
  • 配置
    <!--    方式一:构造方法实例化bean-->
    <!--    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>-->
    <!--    方式二:使用静态工厂实例化bean-->
    <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"></bean>
实例工厂(了解)
  • 实例工厂
package com.itheima.factory;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;

public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
  • 配置–需要先配置一个工厂bean,然后再造一个bean,没有class属性
  <!--    方式三:使用实例工厂实例化bean-->
    <bean id="userFactory" class="com.itheima.factory.UserDaoFactory"></bean>
    <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"></bean>

为了简化上面的流程于是推出第四种:

实例工厂FactoryBean(进阶)(实用)
  • FactoryBean
package com.itheima.factory;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import org.springframework.beans.factory.FactoryBean;

public class UserDaoFactoryBean implements FactoryBean<UserDao> {

    //代替原始实例工厂中创建对象的方法
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }


    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }

    @Override
    public boolean isSingleton() {
        //true表示单例,false表示非单例
        return true;
    }
}

  • 配置
    <!--    方式四,方式三的进阶:使用FactoryBean实例化bean-->
    <bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"></bean>

bean的生命周期

  • ctrl+h表示查看层次结构

在这里插入图片描述

  • Alt+7查看结构

在这里插入图片描述

  • 查看成员方法:Ctrl+F12

在这里插入图片描述

方法一
  • 提供生命周期的控制方法
public class BookDaoImpl implements BookDao {


    public void save() {
        System.out.println("book dao save ... ");
    }

    //表示bean初始化对应的操作
    public void init() {
        System.out.println("init ...");

    }

    //表示bean销毁前对应的操作
    public void destroy() {
        System.out.println("destroy ... ");

    }

}
  • 配置
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"></bean>
方法二
  • 实现InitializingBean,DisposableBean 接口

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }


    public void setBookDao(BookDao bookDao) {
        //在属性设置之前

        System.out.println("set ...");
        this.bookDao = bookDao;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //初始化方法,在属性设置之后
        System.out.println("service init ... ");

    }

    @Override
    public void destroy() throws Exception {
        //销毁操作时方法
        System.out.println("service destroy ... ");

    }
}

  • 注意生命周期的流程:

    • 初始化容器

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

    2.执行构造方法

    3.执行属性注入(set方法)

    4.执行bean初始化方法

  • 使用bean

    • 执行业务操作
  • 关闭/销毁容器

    • 执行bean销毁方法
  • 注:容器关闭前才会触发bean的销毁

    • 关闭容器的方式:

      • 手工关闭容器:

      ConfigurableApplicationContext接口close操作

      • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机

      ConfigurableApplicationContext接口registerShutdownHook()操作

    public static void main(String[] args) {

//        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //注册关闭钩子,在任何时间都可以写这句代码,在虚拟机退出之前会自动退出
        ctx.registerShutdownHook();

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

        //手动关闭
//        ctx.close();
        
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值