Spring使用(一)

1. 核心概念

1.1 IOC(Inversion of Control),控制反转

使用对象时,由主动 new 产生对象转换为由 外部 提供对象,此过程中对象创建控制权由程序转移到
外部,此思想称为控制反转。这里说的“外部”,相当于一个静态工厂,对象有静态工厂创建。

1.2 Spring与IOC的关系

  • Spring技术对IOC思想进行了实现
  • Spring 提供了一个容器,称为 IOC 容器 ,用来充当 IOC 思想中的 " 外部 "
  • IOC 思想中的“ 外部” 指的就是 Spring IOC容器

1.3 IOC容器的作用

  • IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
  • 被创建或被管理的对象在 IOC 容器中统称为 Bean
  • IOC 容器中放的就是一个个的 Bean 对象

1.4 DI(Dependency Inject),依赖注入

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

2. 配置文件

要确定生成哪些bean以及建立bean与bean之间的依赖关系,可以通过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">
    <!--定义bean,
    bean的id属性唯一,也可以加别名name,name属性唯一
    class属性表示生成该bean的类
    scope属性表示bean的作用范围,默认值是singleton,表示单例的,每次获取到的都是同一个对象。prototype表示非单例的,每次获取到的都是新的对象 -->
    <bean id="bookDao" class="com.lan.dao.impl.BookDaoImpl" scope="singleton"/>

    <bean id="bookService" class="com.lan.service.impl.BookServiceImpl">
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体的属性
        ref属性表示引用哪一个bean,或者说注入哪个bean,其值可以是被引用的bean的id或name
        注意,com.lan.service.impl.BookServiceImpl要提供对应的setter方法-->
        <property name="bookDao" ref="bookDao"/>
        <property name="name" value="hello, world"/>
    </bean>
</beans>

bean标签用来定义bean,bean的id属性唯一,class属性标识该bean对应的类,scope属性表示bean的作用范围,默认值是singleton,表示单例的,每次获取到的都是同一个对象。prototype表示非单例的,每次获取到的都是新的对象。

bean/property标签,标识该bean需要注入的属性,name是属性名,ref是引用类型的注入,value是非引用类型的注入。

bean/contructor-arg标签,

3. 初始化IOC容器

App

package com.lan;

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

public class App {
    public static void main(String[] args) {
        // 初始化IOC容器,创建xml中定义的bean,并处理依赖注入
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 从IOC容器中获取id为bookDao的bean
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        // 从IOC容器中获取id为bookService的bean
        BookService bookService = (BookService) ctx.getBean("bookService");
    }
}

BookServiceImpl

package com.lan.service.impl;

import com.lan.dao.BookDao;
import com.lan.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private String name;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    // 提供对应的setter方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void setName(String name) {
        this.name = name;
    }
}

注意,上面提供了要被注入的属性的setter方法,对应xml的bean/property标签,去掉setter方法会注入失败。当然还可以通过构造方法传参的方式进行注入,对应bean/constructor-arg标签。

4. 依赖注入的方式

上面也提到了,依赖注入有两种方式:

  • setter方式,对应xml的bean/property标签
  • 构造方法方法,对应bean/constructor-arg标签

另外,也可以不填写bean/property或者bean/construct-arg,直接根据类型进行自动注入

<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.lan.service.impl.BookServiceImpl" autowire="byType"/>

5. bean的实例化方式

5.1 构造方法的方式

构造方法是bean的默认实例化方式,也是常用的方式

<bean id="bookDao" class="com.lan.dao.impl.BookDaoImpl"/>

5.2 静态工厂的方式

该方式可以友好兼容其它类型的IOC容器

<!-- factory-method指定调用静态工厂类的哪个方法实例化所需要的bean -->
<bean id="orderDao" class="com.lan.factory.OrderDaoFactory" factory-method="getOrderDao"/>

5.3 实例工厂的方式

<bean id="userFactory" class="com.lan.factory.UserDaoFactory"/>
<!-- factory-bean指定实例工厂bean -->
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

5.4 FactoryBean方式

<!-- com.lan.factory.UserDaoFactoryBean实现了FactoryBean接口 -->
<bean id="userDao" class="com.lan.factory.UserDaoFactoryBean"/>

UserDaoFactoryBean

package com.lan.factory;

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

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

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

}

6. bean的生命周期

<!--init-method:设置bean初始化生命周期回调函数-->
<!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

另外,bean可以实现InitializingBean接口来代替init-method配置,实现DisposableBean接口来代替destroy-method配置

7. 加载Properties文件

<!--
classpath:jdbc.properties 表示加载当前工程或者当前jar的类路径下的jdbc.properties
classpath*:*.properties 表示加载当前工程类路径和当前工程所依赖的所有jar包中的所有properties文件
-->
<context:property-placeholder location="classpath*:*.properties"/>

<bean id="bookDao" class="com.lan.dao.impl.BookDaoImpl">
    <property name="name" value="${username}"/>
</bean>

配置<context:property-placeholder>,然后在bean/property的value属性,用${变量名}的方式引用。

注意,若有同名的系统变量,会优先使用系统变量,<context:property-placeholder>增加属性system-properties-mode="NEVER"可以屏蔽系统变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值