SSM核心容器部分

IOC:Inversion of control控制反转-使用对象时由程序中主动new对象转为外部提供对象。

        此过程中对象创建控制权由程序内部转为外部,此思想称为控制反转。

Spring技术对IOC思想提供了实现:

        Spring提供一个容器,称为IOC容器,用来充当IOC思想的“外部”

        IOC容器负责对象的创建、初始化等工作,被创建的对象在IOC容器中被称为Bean

适合交给容器管理的对象:表现层对象、业务层对象、数据层对象、工具对象

不适合交给容器管理的对象:封装实体的域对象

<!-- 1.pom文件中导入Spring对应的坐标spring-context,对应的版本是5.3.21-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.21</version>
</dependency>
<!-- 2.配置bean-->
<bean id="bookDao" class="com.kxg.exercise.dao.impel.BookDaoImpel" name="bookDao1,bokDao2" scope="prototype"/>

bean标签属性介绍:

        id属性:给bean起名字

        class属性:表示给bean定义类型

        name属性:给bean起别名。可以定义多个,是用逗号、分号、空格分隔

        scope属性:定义bean的作用范围。singleton:单例(默认) prototype:非单例

程序内部获取bean可以通过id或name,如果两个都没有得到将抛出异常NoSuchBeanDefinition

// 3.在程序中获取容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    // 可以使用文件系统配置路径:new ClassPathXmlApplicationContext("绝对路径")
    // 一次获取多个容器:new ClassPathXmlApplicationContext("a.xml","b.xml");
// 4.获取容器中的bean
    // 方法一:按照bean名称获取
BookDao bookDao1 = (BookDao)ctx.getBean("bookDao");
    // 方法二:按照bean类型获取(类型唯一)
BookDao bookDao2 = ctx.getBean("BookDao.class");
    // 方法三:使用bean名称获取指定类型
BookDao bookDao3 = ctx.getBean("bookDao", BookDao.class);

经过上面几步,对象的创建成功由程序内部转为程序外部

DI:Dependency Injection-依赖注入

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

<!-- 在spring文件中配置类与类之间的关系:service与dao-->
<bean id="bookService" class="com.kxg.exercise.service.impel.BookServiceImpel">
    <property name="bookDao" ref="bookDao"/>
</bean>

property标签:表示配置当前bean的属性

        name:表示配置哪一个具体的属性

        ref:表示参照哪一个bean(两个类的绑定)

依赖注入的目的:充分解耦

通过控制反转、依赖注入,对象可以直接从外部获取,并且获取到的bean已经绑定了所有的依赖

这样虽然实现了解耦但是同时也出现了很多新问题:

        bean类中的成员变量怎样实现初始化???

        bean是怎样进行实例化的???

        bean的生命周期???

        外部bean怎样进行管理???

因此Spring也提供了很多解决方案。

依赖注入的方式:setter注入、构造器注入

setter注入:

        简单数据类型:在bean类中设置set方法;xml文件中使用property标签value属性注入

        引用数据类型:在bean类中设置set方法;xml文件中使用property标签ref属性注入建立关系

<property name="connectNumber" value="10"/>
<property name="bookDao" ref="bookDao"/>

构造器注入:

        简单类型:bean类中提供构造方法;xml文件中<constructor-atg>标签中name、value属性

        引用类型:bean类中提供构造方法;xml文件中<constructor-atg>标签中name、ref属性

<!-- 引用类型 -->
<constructor-arg name="bookDao" ref="bookDao"/> 
<!-- 简单数据类型 -->
    <!-- 通过参数名称匹配:没有达到程序解耦的问题 -->
<constructor-arg name="connectNumber" value="55"/>
<constructor-arg name="databaseName" value="mysql"/>
    <!-- 通过参数值类型进行匹配,试图实现解耦问题 -->
<constructor-arg type="int" value="55"/>
<constructor-arg type="java.lang.String" value="mysql"/>
    <!-- 通过参数前后位置匹配,试图实现解耦问题 -->
<constructor-arg index="1" value="55"/>
<constructor-arg index="2" value="mysql"/>

通过依赖注入的不同方式,第一个问题得到了解决

bean的实例化:

构造方法:调用类中的无参构造创建实例对象

静态工厂:调用工厂类中的静态方法实例化对象

        1.添加factory-method属性创建类,不能仅配工厂名。否则仅仅创建的是工厂类不是bean对象

        2.factory工厂类中方法添加static才能创建对象

// 静态工厂-static
public static BookDao getBookDao() {
    System.out.println("factory setup...");
    return new BookDaoImpel();
}
<bean id="bookDaoFactory" class="com.kxg.exercise.factory.BookDaoFactory" factory-method="getBookDao"/>

实例工厂:调用静态类中的非静态方法

        容器中配置工厂类

        容器中factory-bean找到相应的工厂类,factory-method找到对应的方法

// 非静态工厂
public BookDao getBookDao_() {
    System.out.println("factory2 setup...");
    return new BookDaoImpel();
}
<!--非静态工厂-->
<bean id="bookDaoFactory1" class="com.kxg.exercise.factory.BookDaoFactory"/>
<bean id="bookDao1" factory-method="getBookDao_" factory-bean="bookDaoFactory1"/>
        

使用FactoryBean实例化

        创建相关FactoryBean类实现FactoryBean接口,实现相关的创建方法getObject

        容器中加载FactoryBean类

public class bookDaoFactoryBean implements FactoryBean<BookDao> {
    // 得到bean实例:代替原始实例工厂中创建对象的方法
    @Override
    public BookDao getObject() throws Exception {
        System.out.println("FactoryBean...");
        return new BookDaoImpel();
    }
}
<!-- FactoryBean-->
<bean id="bookDao2" class="com.kxg.exercise.factory.bookDaoFactoryBean"/>
BookDao bookDao5 = (BookDao) ctx.getBean("bookDao2");
System.out.println(bookDao5);   
   

bean生命周期:

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

        1.类中提供生命周期的控制方法,xml文件中配置生命周期的方法

        2.类实现InitializingBean、DisposableBean接口

初始化容器:创建对象(内存分配);执行构造方法;执行属性注入(set);执行bean初始化方法

使用bean:执行业务操作

关闭/销毁容器:执行bean销毁方法

bean销毁时机:容器关闭前触发bean的销毁

        关闭容器的方法:

                1.手动关闭容器:ConfigurableApplicationContext接口close()操作

                2.注册关闭钩子,在虚拟机退出前先关闭容器在退出虚拟机:ConfigurableApplicationContext接口registerShutdownHook()

接下来就到了最后一个问题:外部bean怎样管理?

以数据源对象为例:

1.spring中开启context命名空间xmlns:context="http://www.springframework.org/schema/context"

 2.在context空间中加载properties文件  

         system-properties-mode="NEVER":不加载系统属性          location="jdbc1.properties,jdbc2.properties:加载多个properties文件          location="classpath:*.properties:加载路径下的所有properties文件标准格式         location="classpath*:*.properties:从类路径或jar包中搜索并加载properties文件   

3.使用属性占位符${}读取properties文件中的属性

<context:property-placeholder location="classpath:*.properties"/>
<bean class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
// 创建数据源对象
DataSource dataSource1 = (DataSource) ctx.getBean("dataSource1");
System.out.println(dataSource1);

此外spring还提供了依赖自动装配:直接在bean标签中使用autowire属性

按类型:autowire="byType"

        使用类型装配时,必须保障容器中相同类型的bean唯一

按名称:autowire="byName"

        使用名称自动装配时,必须保障容器中具有指定名称的bean

1.自动装配用于引用类型注入,不适用于简单类型

2.自动装配优先级低于setter注入与构造器注入,同时出现时自动装配失效

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值