Spring 入门操作 重点掌握基于注解的 Spring开发

1 Sring简介

Spring 是什么?

full - stack 是各层之间都有解决方案,各层代表的是MVC三层架构的软件结构模式不是前后端一起做的全栈

web
service
dao

image.png

Spring 的优势

image.png

image.png

Spring 体系结构

image.png

最下面的 Test 表示这个框架都是可以进行测试的;

Core Container 可以理解为 IOC(控制反转的部分)

2 Spring 的快速入门

1 Spring 开发步骤

image.png

上图的文字描述如下所示:

image.png

传统的开发中,UserServiceImpl 创建 UserDaoImpl 对象是程序员自己创建的,这样子导致了 UserServiceImpl 和 UserDaoImpl 之间的耦合是是非常高的,对于后期的维护不是很方便;现在换一种开发思路,通过配置文件进行编程,实现两者之间的解耦合,提高开发出来的产品的可维护性,减少维护开支;

2 开发步骤实现

3 Spring 的配置文件

1 Bean 标签的基本配置

image.png

2 Bean 标签的范围配置 以及不同 scope 属性下的对象的创建实际

image.png

在 标签的 scope 属性配置了 singleton 以及 prototype 时候 ,UserDaoImpl 创建的次数以及创建的时机都是有所不同的;

具体的不同之处在于:singleton 创建一个对象,在加载完 applicationContext.xml 配置文件之后就创建了一个对象; prototype 在调用 getBean() 方法的时候,创建的对象,这个方法调用几次,就会创建几个对象;

image.png

3 Bean 生命周期配置

初始化方法以及销毁方法都是在 UserDaoImpl 里面实现的;
在这个里面配置初始化方法以及销毁方法,在创建对象之后,会进行一些初始化操作,在手动关闭之后,会执行相关销毁工作;

<bean id="userDao" class="com.luobin.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>

4 Bean 实例化的三种方式

1、无参构造方法实例化

2、工厂静态方法实例化

3、工厂实例方法实例化

<?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">
    <!--约定俗称这个名字 applicationContext-->
    <!--id 与class 里面的实现类进行绑定,以后 spring 可以通过 id 创建 class 里面的 UserDaoImpl 类,实现控制反转,也就是创建类让 spring 框架来完成,不需要程序员自己来创建类 -->
    <!--    <bean id="userDao" class="com.luobin.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>-->

    <!--上面使用了无参数构造的方法创建出来了Bean 对象,下面使用静态工厂的方式创建 Bean 对象-->
    <!--在 class 属性后面需要补上 factory-method 属性,否则使用的是 StaticFactory 里面的无参数构造方法-->
    <!--    <bean id="userDao" class="com.luobin.factory.StaticFactory" factory-method="getUserDao"></bean>-->

    <!--实例工厂的对象创建方式,上面一个是基于无参数构造,一个是基于静态工厂构造,下面使用实例工厂构造-->
    <!--首先需要工厂对象,然后使用工厂对象调用方法,配置文件需要写两处-->
    <!--第一行是创建工厂对象,第二行是使用创建号的工厂对象调用方法,返回创建好的 UserDaoImpl 对象-->
    <bean id="factory" class="com.luobin.factory.DynamicFactory"></bean>
    <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
</beans>

最常用的是无参构造的创建对象;其他两个需要了解即可,遇到具体的应用场景可以使用;

5 Bean 依赖注入分析

在后台代码当中为什么取到bean后要强转成接口类型(UserService)而不是实现类类型(UserServiceImpl)

image.png

依赖注入
image.png

6 引出来依赖注入的概念

image.png

7 依赖注入的方式

如何将 UserDao 注入到 UserService 里面去呢?
通过 Spring 的配置文件,将UserDao 注入到 UserService;注入的方式有两种,下面进行分别演示:

1、set 方法

2、构造方法

set 方法

配置文件

<!--依靠 Spring 进行 UserServiceImpl 对象的创建,让 Spring 进行对象创建的管理-->
<bean id="userService" class="com.luobin.service.impl.UserServiceImpl">
    <!--配置文件完成 UserDao 注入到 UserService name 属性是 set 方法后面的内容,并且将 setUserDao 中的 UserDao 第一个字母变成小写-->
    <property name="userDao" ref="userDao"></property>
</bean>

被注入的实现类 UserServiceImpl

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    /**
     * 通过 set 方法的依赖注入,将 UserDao 注入到 UserService 里面去
     * @param userDao
     */
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
}

注入的类

public class UserDaoImpl implements UserDao {
    /**
     * 没有构造方法的话,jvm 会自动的进行无参构造的,此时自己写了无参数构造,就会使用自己的构造器创建对象
     */
    public UserDaoImpl() {
        System.out.println("UserDaoImpl 对象此时被创建了");
    }

    @Override
    public void save() {
        System.out.println("UserDaoImpl save running...");
    }
}

测试方法

public class UserController {
    public static void main(String[] args) {
        // 读取了一次 配置文件,创建出来了一个 UserDaoImpl 对象,创建出来一个一个 UserServiceImpl 对象
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");

        // 调用 UserService save 方法的时候,因为在 save 方法中再一次的读取了配置文件,所以创建了两个对象
        userService.save();
    }
}
set 方法注入之 P 命名空间注入 (更加的简便)

image.png

构造方法注入

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">
    <!--约定俗称这个名字 applicationContext-->
    <!--id 与class 里面的实现类进行绑定,以后 spring 可以通过 id 创建 class 里面的 UserDaoImpl 类,实现控制反转,也就是创建类让 spring 框架来完成,不需要程序员自己来创建类 -->
    <bean id="userDao" class="com.luobin.dao.impl.UserDaoImpl"></bean>

    <bean id="userService" class="com.luobin.service.impl.UserServiceImpl">
        <!--name 是构造方法的参数名字 ref 表示的是引用容器中的 <bean> 的id 作为依赖注入-->
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>
</beans>

UserServiceImpl 这里使用了构造器的方式

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    /**
     * 通过构造方法进行注入
     * @param userDao
     */
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserServiceImpl() {
    }

    @Override
    public void save() {
        userDao.save();
    }

UserDao 代码不变

public class UserDaoImpl implements UserDao {
    /**
     * 没有构造方法的话,jvm 会自动的进行无参构造的,此时自己写了无参数构造,就会使用自己的构造器创建对象
     */
    public UserDaoImpl() {
        System.out.println("UserDaoImpl 对象此时被创建了");
    }

    @Override
    public void save() {
        System.out.println("UserDaoImpl save running...");
    }
}

测试代码不变

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");

        // 容器里面已经将 UserDao UserService 两个对象创建了,这里直接取到创建好的对象调用相关的方法即可;
        userService.save();
    }
}

8 Bean 依赖注入的数据类型

普通数据类型

引用数据类型

集合数据类型

配置文件
<?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">

    <!--构造方法注入 把 dao 注入到 service 层-->
    <bean id="userService" class="com.luobin.service.impl.UserServiceImpl">
        <!--name 是构造方法的参数名字-->
        <!--ref 表示的是下面的引用容器中的 <bean> 里面 dao  的id 作为依赖注入-->
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

    <!--集合注入 把集合注入到 dao层-->
    <bean id="userDao" class="com.luobin.dao.impl.UserDaoImpl">
        <!--name: 注入的数据类型创建出来的变量名-->
        <property name="strList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>

        <property name="userMap">
            <map>
                <entry key="u1" value-ref="user1"></entry>
                <entry key="u2" value-ref="user2"></entry>
            </map>
        </property>

        <property name="properties">
            <props>
                <prop key="p1">ppp1</prop>
                <prop key="p2">ppp2</prop>
                <prop key="p3">ppp3</prop>
            </props>
        </property>
    </bean>

    <!--为了配合上面的 map 注入,因为注入的是对象,这里需要创建对象-->
    <bean id="user1" class="com.luobin.domain.User">
        <!--在 User 类里面也是存在 get set 方法的,这里可以把数值注入进去 -->
        <property name="name" value="tom"/>
        <property name="addr" value="tianjin"/>
    </bean>

    <bean id="user2" class="com.luobin.domain.User">
        <!--在 User 类里面也是存在 get set 方法的,这里可以把数值注入进去 -->
        <property name="name" value="lucy"/>
        <property name="addr" value="beijing"/>
    </bean>
</beans>
UserDaoImpl 代码
package com.luobin.dao.impl;

import com.luobin.dao.UserDao;
import com.luobin.domain.User;

import java.util.List;
import java.util.Map;
import java.util.Properties;


public class UserDaoImpl implements UserDao {
    private List<String> strList;
    private Map<String, User> userMap;
    private Properties properties;

    private String username;
    private int age;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setStrList(List<String> strList) {
        this.strList = strList;
    }

    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }

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

    /**
     * 没有构造方法的话,jvm 会自动的进行无参构造的,此时自己写了无参数构造,就会使用自己的构造器创建对象
     */
    public UserDaoImpl() {
        System.out.println("UserDaoImpl 对象此时被创建了");
    }

    @Override
    public void save() {
        System.out.println(strList);
        System.out.println(userMap);
        System.out.println(properties);
        System.out.println("UserDaoImpl save running...");
    }
}
UserServiceImpl
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    /**
     * 通过构造方法进行注入
     * @param userDao
     */
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
}
User 类代码
package com.luobin.domain;

/**
 * @author Doraemon
 * @date 2022/3/18 11:12 上午
 * @version 1.0
 */
public class User {
    private String name;
    private String addr;

    public String getName() {
        return name;
    }

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

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", addr='" + addr + ''' +
                '}';
    }
}

Controller 测试类代码

package com.luobin.demo;

import com.luobin.service.UserService;
import com.luobin.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Doraemon
 * @date 2022/3/17 9:15 下午
 * @version 1.0
 */
public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");

        // 容器里面已经将 UserDao UserService 两个对象创建了,这里直接取到创建好的对象调用相关的方法即可;
        userService.save();
    }
}

4 Spring 相关 api

1 ApplicationContext 继承体系

image.png

2 ApplicationContext 实现类

就是对于配置文件的加载,第一个是 resource 下面的直接读取配置文件,第二个是使用配置文件在系统中的绝对位置进行配置文件的读取,第三个使用了注解的方式;

image.png

3 getBean() 方法使用

里面传入参数可以有两种数据类型,一个使用 bean 配置文件的 id 获取创建好的对象;一个是 Class 实例

image.png

bean 存在多个使用 id 的方式 getBean ,bean 存在一个 可以使用 Class 实例获取

4 重要知识点

image.png

5 Spring 配置数据源

1 数据源(连接池)的作用

数据源为了提高程序的性能出现的;

image.png

2 数据源开发步骤

image.png

什么是数据库连接池?简单的概念理解

为了了避免频繁地创建数据库连接,工程师们提出了数据库连接池技术。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。

接下来,通过一张图来简单描述应用程序如何通过连接池连接数据库,如图2-1所示。

从图2-1中可以看出,数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,当应用程序访问数据库时并不是直接创建Connection,而是向连接池“申请”一个Connection。

如果连接池中有空闲的Connection,则将其返回,否则创建新的Connection。 使用完毕后,连接池会将该Connection回收,并交付其他的线程使用,以减少创建和断开数据库连接的次数,提高数据库的访问效率;

image.png

3 数据源的手动配置

package com.luobin.test;

import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.sql.Connection;
import java.util.ResourceBundle;

/**
 * @author Doraemon
 * @date 2022/3/18 12:10 下午
 * @version 1.0
 */
public class DataSourceTest {
    @Test
    // 测试手动创建 c3p0 数据源
    public void test() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();

        dataSource.setDriverClass("com.mysql.jdbc.Driver");

        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/data");
        dataSource.setUser("root");
        dataSource.setPassword("9842213764");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

    @Test
    // 测试手动创建 druid 数据源
    public void test2() throws Exception{
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        dataSource.setUrl("jdbc:mysql://localhost:3306/data");
        dataSource.setUsername("root");
        dataSource.setPassword("9842213764");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

    @Test
    // 按照抽取配置文件的形式配置数据连接池
    // 前面使用了硬编码的形式,不是特别的好,这里将相关参数配置到文件中,直接读取配置文件即可
    public void test3() throws Exception{
        // 使用 bundle 的形式配置数据库
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
        String driver = rb.getString("jdbc.driver");
        String url = rb.getString("jdbc.url");
        String username = rb.getString("jdbc.username");
        String password = rb.getString("jdbc.password");

        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);

        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }
}

jdbc.properties 配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/data
jdbc.username=root
jdbc.password=9842213764

4 Spring 配置数据库连接池 ,Spring 产生数据池对象

为什么产生数据池对象?

为了方便的管理数据库的连接以及数据库的关闭操作,提升程序的运行效率;

在Spring 进行配置的时候,创建这个数据源对象使用 bean 标签进行创建,里面注入需要使用的参数即可;

下面是使用配置文件的形式在 Spring 中配置了数据库连接池,创建了 dataSource 类,里面使用了 set 方法的依赖注入;

<?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 id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--使用 set 方法进行参数的注入-->
        <!--进行参数的注入-->
        <!--name 是 setDriverClass 的 DriverClass 第一个字母的小写-->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/data"></property>
        <property name="user" value="root"></property>
        <property name="password" value="9842213764"></property>
    </bean>
</beans>

上面的配置参数中存在“ ” 手动输入的数据库的信息,可以在 applicationContext.xml 里面将 jdbc.properties 文件直接读取进去,使用 ${} 的形式将参数配置到 Spring 配置文件中;

image.png

image.png

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      ">

    <!--加载外部的 properties 文件-->
    <!--将外部的 jdbc.properties 配置文件加载到了 resource 里面去-->
    <!--在这个位置将 数据路连接的配置文件加载进来,下面只是需要使用 ${} 的形式将参数确定下来-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--使用 set 方法进行参数的注入-->
        <!--进行参数的注入-->
        <!--name 是 setDriverClass 的 DriverClass 第一个字母的小写-->
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
</beans>

6 Spring 注解开发 重点 使用注解就不需要使用 xml 配置对象以及对象的注入 简化开发

Spring 注解主要是为了替代 bean 标签

Spring 是一个轻代码,中配置的文件,此时使用注解,可以简化开发流程,简化配置,提高开发速度;

1 Spring 原始注解 较早出现的注解

image.png

使用注解开发时候需要注意:在 applicationContext.xml 里面需要配置组件扫描,否则运行的过程中会出现错误的;

image.png

UserDaoImpl

package com.luobin.dao.impl;

import com.luobin.dao.UserDao;
import org.springframework.stereotype.Component;

/**
 * @author Doraemon
 * @date 2022/3/18 3:24 下午
 * @version 1.0
 */

// <bean id="userDao" class="com.luobin.dao.impl.UserDaoImpl"></bean>
@Repository("userDao")
public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("save running...");
    }
}

UserServiceImpl

package com.luobin.service.impl;

import com.luobin.dao.UserDao;
import com.luobin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * @author Doraemon
 * @date 2022/3/18 3:25 下午
 * @version 1.0
 */

/**
 *     <bean id="userService" class="com.luobin.service.impl.UserServiceImpl">
 *         <!--name setUserDao 的后面单词的前一个小写,表示使用 set 方法进行对象的注入,从哪儿个方法进行注入-->
 *         <!--ref 表示注入 具体的对象是什么-->
 *         <property name="userDao" ref="userDao"></property>
 *     </bean>
 *
 *     原来的创建对象以及对象的注入基于配置文件,为了简化开发,这里使用注解的形式
 */
@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired// 自动注入
    @Qualifier("userDao") // 需要注入的 id @Autowired @ Qualifier 相当于 <property name="userDao" ref="userDao"></property>
    private UserDao userDao;

    // 使用 set 方法在 service 注入 dao
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        // 调用数据库的 save 方法
        userDao.save();
    }
}

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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      ">

    <!--加载外部的 properties 文件-->
    <!--将外部的 jdbc.properties 配置文件加载到了 resource 里面去-->
    <!--在这个位置将 数据路连接的配置文件加载进来,下面只是需要使用 ${} 的形式将参数确定下来-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--使用注解进行开发的时候 配置组件扫描,指定哪儿个包以及其子包下的 bean 需要进行扫描以便识别使用注解配置的类-->
    <!--告诉 Spring 扫描写的代码,找到注解的位置,创建相关的对象,并且实现注入,方便我再后面直接调用方法-->
    <context:component-scan base-package="com.luobin"></context:component-scan>
</beans>

测试代码

package com.luobin.web;

import com.luobin.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Doraemon
 * @date 2022/3/18 3:47 下午
 * @version 1.0
 */
public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

1 关于 Component Repository Service Controller

直接使用 Component 实例化对象,语义不够明显,不能一眼看出来这是什么层上面的对象,所以使用上述的三种注解,区分在不同层使用不同的注解即可;
image.png

2 Spring 新注解 晚一点出来的注解

为什么出现新注解?其发明出来是为了解决什么问题呢?

在上面学习的注解中,不能完全的代替 xml 配置文件,新注解就是为了使用注解的方法完全的代替 xml 的配置文件,达到高效的开发效率;常见的新注解有如下:

image.png

image.png
基于注解核心配置类实现

/**
 * Configuration 就是一个标志
 *  标志这个类是一个 Spring 核心配置类
 *      其思想就是既然 xml 太麻烦,那就不同 xml 进行配置了,但是该有的配置还是需要有的,配置到什么地方呢?创造出来的配置类
 *      可以放置一些简单的配置;
 */
// 申明这是一个配置文件
@Configuration
// <context:component-scan base-package="com.luobin"></context:component-scan>
@ComponentScan("com.luobin") // 进行注解的扫描,扫描的是一个文件夹

// import 总的配置加载分配置文件
@Import(DataSourceConfiguration.class)
public class SpringConfiguration {

}

基于注解的非核心配置类,核心配置类需要导入

// <context:property-placeholder location="classpath:jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    // 下面是没有办法解析 SEL 的,也就是不能解析 ${} 所以使用 @Value 的注入方式
    @Value("jdbc.driver")
    private String driver;

    @Value("jdbc.url")
    private String url;

    @Value("jdbc.username")
    private String username;

    @Value("jdbc.password")
    private String password;


    @Bean("dataSource") // Spring 会将当前方法的返回值用指定名称存储到 Spring 容器中
    public DataSource getDataSource() throws Exception {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();

        dataSource.setDriverClass(driver);

        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);

        return dataSource;
    }

}

测试代码

public class UserController {
    public static void main(String[] args) {
        // 使用了注解的方式,加载的不是 xml 的配置文件,加载的是配置类
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

7 Spring 整合Junit

原来存在的问题

每次在测试的时候,都是需要加上去这两行代码不是十分的方便

image.png

解决办法

image.png

集成步骤

image.png

package com.luobin.test;

import com.luobin.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @author Doraemon
 * @date 2022/3/18 5:48 下午
 * @version 1.0
 */

// 使用 Spring 提供的一个内核去跑,使用 Spring 的一个内核去跑
@RunWith(SpringJUnit4ClassRunner.class)

// 指定配置文件的位置
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunitTest {
    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

    @Test
    public void test1() throws SQLException {
        userService.save();
        System.out.println(dataSource.getConnection());
    }
}

Spring web 环境集成

ApplicationContext 获取方式

image.png

不处理的话在每一个Servlet 类里面都要创建容器,显然是有一点不合适的;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值