Spring ioc 完全注解

24 阅读3分钟

基于注解、配置类方式整合三层架构组件

三层架构案例,模拟查询全部学生(学生表)信息 image.png

数据库准备

create database studb;

use studb;

CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  gender VARCHAR(10) NOT NULL,
  age INT,
  class VARCHAR(50)
);

INSERT INTO students (id, name, gender, age, class)
VALUES
  (1, '张三', '男', 20, '高中一班'),
  (2, '李四', '男', 19, '高中二班'),
  (3, '王五', '女', 18, '高中一班'),
  (4, '赵六', '女', 20, '高中三班'),
  (5, '刘七', '男', 19, '高中二班'),
  (6, '陈八', '女', 18, '高中一班'),
  (7, '杨九', '男', 20, '高中三班'),
  (8, '吴十', '男', 19, '高中二班');

项目创建

image.png 项目的目录文件夹
image.png

Maven 依赖导入

<!-- pom.xml -->
<dependencies>
      <!--spring context依赖-->
      <!--当你引入 SpringContext 依赖之后,表示将 Spring 的基础依赖引入了-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>6.0.6</version>
      </dependency>
      <!-- 数据库驱动和连接池-->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.25</version>
      </dependency>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.2.8</version>
      </dependency>
      <dependency>
            <groupId>jakarta.annotation</groupId>
            <artifactId>jakarta.annotation-api</artifactId>
            <version>2.1.1</version>
       </dependency>
      <!-- spring-jdbc -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>6.0.6</version>
      </dependency>
</dependencies>

写完依赖后需要刷新

  1. 右侧 Maven 面板
  2. 点击 Sync Project
  3. 下载依赖

image.png

配置 JDBCProperties 数据库连接信息

在 resources 下创建 jdbc.properties 文件

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/studb?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
jdbc.username=root
jdbc.password=XXX
配置项作用
jdbc.driver数据库驱动类
jdbc.url数据库连接地址
jdbc.username数据库用户名
jdbc.password数据库密码

实体类准备

package com.study.java;

public class Student {
    private Integer id;
    private String name;
    private String gender;
    private Integer age;
    private String classes;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getClasses() {
        return classes;
    }
    public void setClasses(String classes) {
        this.classes = classes;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", classes='" + classes + '\'' +
                '}';
    }
}

三层架构搭建和实现

  • Controller
@Controller
public class StudentController {
    @Autowired
    private StudentService studentService; // 注入 service

    public void  findAll(){
        List<Student> studentList =  studentService.findAll();
        System.out.println("studentList = " + studentList);
    }
}
  • Service
// StudentService 接口
public interface StudentService {
    /**
     * 查询全部学员业务
     * @return
     */
    List<Student> findAll();
}
// 实现类 StudentServiceImpl
@Service
public class StudentServiceImpl  implements StudentService {
    @Autowired
    private StudentDao studentDao;
    /**
     * 查询全部学员业务
     * @return
     */
    @Override
    public List<Student> findAll() {
        List<Student> studentList =  studentDao.queryAll();
        return studentList;
    }
}
  • DAO
// 接口
public interface StudentDao {
    /**
     * 查询全部学生数据
     * @return
     */
    List<Student> queryAll();
}
// 实现类
@Repository
public class StudentDaoImpl implements StudentDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询全部学生数据
     * @return
     */
    @Override
    public List<Student> queryAll() {
        String sql = "select id , name , age , gender , class as classes from students ;";
        /*
          query可以返回集合!
          BeanPropertyRowMapper就是封装好RowMapper的实现,要求属性名和列名相同即可
         */
        List<Student> studentList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));
        return studentList;
    }
}

三层架构 IOC 配置类

上述操作配置好了类的结构吗,现在需要做 IOC 配置,否则上面声明的类没办法加入到 IOC 容器中。

// 标识这是一个 Spring 配置类,Spring 在启动时会解析这个类
@Configuration
// 让 Spring 扫描指定包下的组件,并自动注册 Bean。@Component、@Service、@Controller、@Repository 等注解的类,
@ComponentScan(basePackages = "com.study.java")
/* 引入外部的属性配置文件 jdbc.properties,这样就可以在类中使用 @Value 注解来注入配置文件中的值。*/
@PropertySource("classpath:jdbc.properties") // 引入外部配置文件
public class JavaConfig {
    // 从 jdbc.properties 文件中读取对应 key 的值,并注入到成员变量中。
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    // 向 IOC 容器注册一个 Bean,类型 DruidDataSource,Bean 名称是:dataSource
    // Spring 容器关闭时执行,调用该 Bean 的 close() 方法,dataSource.close(),关闭数据库连接池。
    // 没有声明作用域就是单例的,所有地方注入的都是同一个对象
    @Bean(destroyMethod = "close")
    public DruidDataSource dataSource() {
        // 创建数据源对象
        DruidDataSource dataSource = new DruidDataSource();
        // 设置数据库连接信息
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        // Bean 实例对象
        return dataSource;
    }
    // Bean 作用域,每次获取 Bean 都会创建新对象
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean // 先找容器里的 DataSource,自动注入
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        // 数据库操作工具类,简化 JDBC 操作
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
}

测试

// 测试类
public class SpringIocTest {
    @Test
    public void test () {
        // 创建 IOC 容器
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(JavaConfig.class);
        StudentController studentController = applicationContext.getBean(StudentController.class);
        // 调用 Controller 的方法,模拟调用接口
        studentController.findAll();
    }
}

注意 如果 @Test 没有生效,则需要安装 junit

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

image.png