Spring框架核心IOC的使用:IOC的作用+Bean管理+实例化Bean的方式+DI依赖注入

Spring框架合集:
Spring框架核心IOC的使用:IOC的作用+Bean管理+实例化Bean的方式+DI依赖注入
Spring框架核心IOC的使用:配置式开发+注解式开发+纯注解式开发
Spring框架整合junit:包含配置文件的方式以及纯注解开发的方式

maven下载配置可以参考:maven配置

一、项目环境搭建

1.1 新建maven项目

点击新建项目,选择创建一个maven项目
在这里插入图片描述
在这里插入图片描述

1.2 配置maven

在这里插入图片描述
改成本地maven的路径
在这里插入图片描述
在pom文件中创建dependencies,在里面可以添加坐标依赖
在这里插入图片描述
打开Maven Repository: Search/Browse/Explore (mvnrepository.com)
搜索需要的jar包,添加坐标依赖之后,maven会帮助导入项目需要的资源
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在pom文件中添加坐标依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

1.3 配置applicationContext.xml

目录层级

在这里插入图片描述

在resources创建配置文件applicationContext.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">

</beans>

在这里插入图片描述

二、认识IOC

IOC控制反转:将对象的创建反转给spring框架,主要作用就是降低了程序的耦合度

下面通过一个例子,传统方式创建对象和使用IOC的方式创建对象,来简单体会一下IOC

首先在service下创建好需要的类

在这里插入图片描述

UserService接口

public interface UserService {
    public void hello();
}

UserServiceImpl类

public class UserServiceImpl implements UserService {
    @Override
    public void hello() {
        System.out.println("hello");
    }


}

接着在test下的java目录下创建UserServiceTest类进行测试
在这里插入图片描述

加入@Test注解是为了让方法运行

其中的run方法是传统创建对象,run1是用springIOC的方式创建对象

public class UserServiceTest {


    //传统创建对象方法
    @Test
    public void run(){
        UserService userService = new UserServiceImpl();
        userService.hello();
    }

    //用springIOC的方式创建对象,ioc是一个map key是对象的标识,value是ioc创建的对象
    @Test
    public void run1(){
        //创建spring ioc工厂,加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //FileSystemXmlApplicationContext另一种,配置文件在磁盘

        //获取bean对象,返回的是Object对象,强转
        UserService userService = (UserService) ac.getBean("xx");
        //调用方法
        userService.hello();

    }
}

使用用springIOC的方式创建对象,还要配置applicationContext.xml文件,在beans中加入,创建好ioc工厂之后可以通过id拿到需要的class,通过程序创建类底层是反射

<!--    id:创建类的标识 class:需要创建哪个类-->
    <bean id="xx" class="com.service.impl.UserServiceImpl"></bean>

ApplicationContext接口,这个工厂接口,使用该接口可以获取具体的bean对象,该接口下有两个具体的实现类

  • ClassPathXmlApplicationContext,加载类路径下的spring配置文件(常用)
  • FileSystemXmlApplicationContext,加载本地磁盘下的spring配置文件,项目与配置文件分离管理(不常用)

三、bean管理

3.1 bean中属性的介绍

  • id属性:bean起个名字,唯一性,取值要求:必须以字母开始,可以使用字母、数字、连字符、下划线,不能出现特殊字符
  • class属性:bean对象的全路径
  • scope属性:表示bean对象的作用范围
    • ​ singleton:单例(默认)最常用的方式,生命周期跟配置文件一样,加载配置文件,实例创建
    • ​ prototype:多例,不是加载配置文件的时候创建实例的,而是获取实例时才创建实例
    • ​ request:多例,不常用,应用在web项目中,每次http请求的时候会创建一个新的实例
    • ​ session:多例,不常用,应用在web项目中,同一个http session共享一个实例
  • init-method:bean对象创建时可以配置一个指定方法并自动调用
  • destroy-method:bean对象销毁时可以配置一个指定方法并自动调用

3.2 具体示例

3.2.1 bean对象的生命周期

在UserServiceImpl类中生成构造方法

    public UserServiceImpl() {
        System.out.println("我创建了");
    }

修改applicationContext.xml文件,scope改为singleton

    <bean id="xx" class="com.service.impl.UserServiceImpl" scope="singleton"></bean>

修改测试类UserServiceTest中的run1方法,只是加载配置文件,然后运行

    @Test
    public void run1(){
        //创建spring ioc工厂,加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //FileSystemXmlApplicationContext另一种,配置文件在磁盘

        //获取bean对象,返回的是Object对象,强转
        //UserService userService = (UserService) ac.getBean("xx");
        //调用方法
        //userService.hello();

    }

运行结果

在这里插入图片描述

然后修改applicationContext.xml,然后运行

    <bean id="xx" class="com.service.impl.UserServiceImpl" scope="prototype"></bean>

运行结果

在这里插入图片描述

此时并未输出“我创建了”,修改测试类,然后再运行

    @Test
    public void run1(){
        //创建spring ioc工厂,加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //FileSystemXmlApplicationContext另一种,配置文件在磁盘

        //获取bean对象,返回的是Object对象,强转
        UserService userService = (UserService) ac.getBean("xx");
        //调用方法
        userService.hello();

    }

运行结果

在这里插入图片描述

从这个例子中可以体会到singleton与prototype生命周期的不同

3.2.2 init-method与destroy-method

修改UserServiceImpl类

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

修改applicationContext.xml

    <bean id="xx" class="com.service.impl.UserServiceImpl" init-method="init"></bean>

运行测试类中的run1方法,会发现自动调用了init方法,destroy-method同理

在这里插入图片描述

四、实例化bean的三种方式

4.1 无参的构造方法

默认是无参的构造方法(默认方式,基本上都是使用这种)

<bean id="xx" class="com.service.impl.UserServiceImpl" init-method="init" ></bean>

注意:如果构造方法有参数,此时一定要保留无参的构造方法,不然程序会报错

ioc反射底层默认调用的是无参的构造方法

4.2 静态工厂实例化方式

静态工厂实例化方式,好处是可以自己编写业务逻辑

首先创建com.util包,然后创建一个StaticFactory类,在类中我们可以编写业务逻辑,只需要最后返回一个User类

public class StaticFactory {
    public static UserService createUs(){
        System.out.println("通过静态工厂的方式");
        //编写很多业务逻辑 ... ...
        return new UserServiceImpl();
    }
}

配置applicationContext.xml文件,这里的类是编写业务逻辑的类,方法调用的是createUs,返回需要的类

    <bean id="xx" class="com.util.StaticFactory" factory-method="createUs"></bean>

在测试类中运行run1方法

在这里插入图片描述

4.3 实例化工厂实例化方式

实例化工厂实例化方式,好处是可以自己编写业务逻辑

在com.util包下创建一个DFactory类

public class DFactory {
    public  UserService createUs(){
        System.out.println("通过实例化工厂的方式");
        //编写很多业务逻辑 ... ...
        return new UserServiceImpl();
    }
}

配置applicationContext.xml文件,先把DFactory交给bean管理,方法调用的是createUs,返回需要的类

<bean id="DFactory" class="com.util.DFactory" ></bean>
<bean id="xx" factory-bean="DFactory" factory-method="createUs"></bean>

运行测试类

@Test
public void run1(){
    //创建spring ioc工厂,加载spring的配置文件
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    //FileSystemXmlApplicationContext另一种,配置文件在磁盘

    //获取bean对象,返回的是Object对象,强转
    UserService userService = (UserService) ac.getBean("xx");
    //调用方法
    userService.hello();

}

在这里插入图片描述

五、DI依赖注入

Dependency Injection 依赖注入在spring框架负责创建bean对象时,动态的将依赖对象注入到其他bean对象中

可以理解为赋值

5.1 认识DI

在dao层中创建一个接口UserDao,再创建一个实现类UserDaoImpl

public interface UserDao {
    public void hello();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void hello() {
        System.out.println("持久层你好");
    }
}

然后在service层创建UserService接口,再创建一个实现类UserServiceImpl

public interface UserService {
    public void hello();
}

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    @Override
    public void hello() {
        System.out.println("业务层你好");
        userDao.hello();
    }
}

目录结构

在这里插入图片描述

此时我们想通过业务层来调用dao层中的方法,在UserServiceImpl创建了一个UserDao的对象,但是如果此时运行的话,会报空指针的错误。因此我们修改一下UserServiceImpl类,里面new一个UserDaoImpl

public class UserServiceImpl implements UserService {

	private UserDao userDao = new UserDaoImpl();
    @Override
    public void hello() {
        System.out.println("业务层你好");
        userDao.hello();
    }
}

修改之后运行结果

在这里插入图片描述

这种赋值的方式就是依赖注入,就是给变量赋值。通过这种方式,业务层可以调用持久层的方法

5.2 依赖注入的方式

5.2.1 属性的set方法注入值的方式

修改UserServiceImpl类,注意这种方式必须有set方法

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private String name;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "UserServiceImpl{" +
                "userDao=" + userDao +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public void hello() {
        System.out.println("业务层你好");
        userDao.hello();
    }
}

修改配置文件applicationContext.xml,此时为name和userDao赋值

    <bean id="userDaoImpl" class="com.dao.impl.UserDaoImpl"></bean>
    <bean id="xx" class="com.service.impl.UserServiceImpl">
        <property name="name" value="lm"></property>
        <property name="userDao" ref="userDaoImpl"></property>
    </bean>

其中的property标签是为类中的变量赋值

  • 简单类型(基本类型+字符串)property标签使用value属性赋值
  • 自定义应用类 property标签使用ref属性赋值

先把UserDaoImpl交给IOC工厂管理,等到用时使用ref赋值

在UserServiceTest类中运行run1方法

@Test
    public void run1(){
        //创建spring ioc工厂,加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //FileSystemXmlApplicationContext另一种,配置文件在磁盘

        //获取bean对象,返回的是Object对象,强转
        UserService userService = (UserService) ac.getBean("xx");
        //调用方法

        System.out.println(userService);

    }

在这里插入图片描述

5.2.2 构造方法注入值的方式

修改UserServiceImpl类,注意使用这种方式时要保留类的无参构造方法,因为实例化bean默认调用的是无参的构造方法,如果不保留的话程序报错

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private String name;

    public UserServiceImpl() {
    }

    public UserServiceImpl(UserDao userDao, String name) {
        this.userDao = userDao;
        this.name = name;
    }

    @Override
    public String toString() {
        return "UserServiceImpl{" +
                "userDao=" + userDao +
                ", name='" + name + '\'' +
                '}';
    }


}

修改applicationContext.xml,这里使用的是constructor-arg标签,注意构造方法的赋值要与配置文件中保持一致不能多也不能少,这里的配置文件中是有name和userDao,如果只有name那么构造方法也应该只有name一个参数

<bean id="userDaoImpl" class="com.dao.impl.UserDaoImpl"></bean>
<bean id="xx" class="com.service.impl.UserServiceImpl">
    <constructor-arg name="name" value="Jack"></constructor-arg>
    <constructor-arg name="userDao" ref="userDaoImpl"></constructor-arg>
</bean>

运行run1方法

在这里插入图片描述

六、对其他数据类型的注入

这里使用都是set方法注入值的方式

6.1 对数组的注入

创建CollectionBean类

public class CollectionBean {
    private String[] arr;

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arr=" + Arrays.toString(arr) +
                '}';
    }
}

配置applicationContext.xml文件,为arr赋值

<bean id="cb" class="com.service.CollectionBean">
    <property name="arr">
        <array>
            <value>李明</value>
            <value>xiaomi</value>
        </array>
    </property>
</bean>

在测试类中创建方法,查看结果

@Test
public void run2(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    CollectionBean cB = (CollectionBean) ac.getBean("cb");

    System.out.println(cB);

}

在这里插入图片描述

6.2 对可变数组的注入

修改CollectionBean类

public class CollectionBean {
    private List<String> list;
    public void setList(List<String> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "list=" + list +
                '}';
    }
}

修改配置文件

<bean id="cb" class="com.service.CollectionBean">
    <property name="list">
        <list>
            <value>李明</value>
            <value>xiaomi</value>
        </list>
    </property>
</bean>

6.3 对map的注入

修改CollectionBean类

public class CollectionBean {

    private Map<String,String> map;

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "map=" + map +
                '}';
    }
}

修改配置文件

    <bean id="cb" class="com.service.CollectionBean">
        <property name="map">
            <map>
                <entry key="xiaomi" value="SU7"></entry>
                <entry key="byd" value="海豹"></entry>

            </map>
        </property>
    </bean>

6.4 对Properties注入

修改CollectionBean类

public class CollectionBean {

    private Properties properties;

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "properties=" + properties +
                '}';
    }
}

修改配置文件

    <bean id="cb" class="com.service.CollectionBean">
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>

6.5 对自定义类型的注入

修改CollectionBean类

public class CollectionBean {

    private UserService[] userServices;

    public void setUserServices(UserService[] userServices) {
        this.userServices = userServices;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "userServices=" + Arrays.toString(userServices) +
                '}';
    }
}

修改配置文件

    <bean id="userS" class="com.service.impl.UserServiceImpl"></bean>
    <bean id="cb" class="com.service.CollectionBean">
        <property name="userServices">
            <ref bean="userS"></ref>
        </property>
    </bean>

七、多配置文件的加载方式

如果有多个配置文件,如何使用多配置文件开发

在这里插入图片描述

1、在主配置文件中使用< import >标签

<import resource="applicationContext2.xml"></import>

2、创建工厂时直接加载多个配置文件

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext.xml");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值