基于注解+配置类方式整合三层架构组件
大约 5 分钟
项目实践:基于注解+配置类方式整合三层架构组件
1.需求案例:搭建一个三层架构案例,模拟查询全部用户(用户表)信息,持久层使用JdbcTemplate和Druid技术,使用注解方式进行组件管理,使用Java配置类代替XML配置文件。
2.项目架构:参考借鉴《Spring项目实践——IoC/DI案例》
3.数据模型:
CREATE TABLE user (
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
4.实践要求:
(1) 参考借鉴《Spring项目实践——IoC/DI案例》实现
(2) 使用Junit5以上版本完成测试。
项目实现
项目目录
一、数据库
1、添加新的数据库(usermis):
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS user;
CREATE TABLE user (
id int NOT NULL AUTO_INCREMENT,
username varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
password varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO user VALUES (1, 'Peng Yuning', '8WvErMonB8');
INSERT INTO user VALUES (2, 'Takahashi Kasumi', 'YUEsievZJM');
INSERT INTO user VALUES (3, 'Bruce Rodriguez', 'oSKkZSv4wm');
INSERT INTO user VALUES (4, 'Lau Ching Wan', 'F0WfooyAy2');
INSERT INTO user VALUES (5, 'Lui Sze Kwan', 'Msou1bJ0vv');
INSERT INTO user VALUES (6, 'Ernest Crawford', '6BZpnzERaC');
INSERT INTO user VALUES (7, 'Juan Castillo', '8enHa9Ay1D');
INSERT INTO user VALUES (8, 'Fu Wing Kuen', 'kQbmCoKWxa');
INSERT INTO user VALUES (9, 'Valerie Harrison', 'MaIuoHAGHQ');
INSERT INTO user VALUES (10, 'Margaret Henderson', 'pBCv42yItl');
SET FOREIGN_KEY_CHECKS = 1;
二、项目创建
1、配置xml文件,导入Spring相关依赖和需求相关技术的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>WebLesson</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>Spring-Practice-01</module>
</modules>
<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.annotation/jakarta.annotation-api -->
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.6</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!--Spring JDBC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!--spring-test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>6.0.6</version>
</dependency>
<!--声明式事务依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
</project>
2、构建三层架构,并编写相关代码,创建接口并重写方法,然后使用Spring框架标签进行托管。
User.java 实体类
package com.Ek0wraith.dao.pojo;
import lombok.Data;
/**
* ClassName: User
* Package: com.Ek0wraith.dao.pojo
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 15:56
* @Version 1.0
*/
@Data
public class User {
private Integer id;
private String username;
private String password;
}
UserDao.java 接口
package com.Ek0wraith.dao;
import com.Ek0wraith.dao.pojo.User;
import java.util.List;
/**
* ClassName: UserDao
* Package: com.Ek0wraith.dao
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 15:58
* @Version 1.0
*/
public interface UserDao {
List<User> queryAll();
}
UserDaoImpl.java
package com.Ek0wraith.dao;
import com.Ek0wraith.dao.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* ClassName: UserDaoImpl
* Package: com.Ek0wraith.dao
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 15:56
* @Version 1.0
*/
@Repository
public class UserDaoImpl implements UserDao{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<User> queryAll() {
String sql = "select * from users;";
List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
return userList;
}
}
UserService.java
package com.Ek0wraith.service;
import com.Ek0wraith.dao.pojo.User;
import java.util.List;
/**
* ClassName: UserService
* Package: com.Ek0wraith.service
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:13
* @Version 1.0
*/
public interface UserService {
List<User> findAll();
}
UserServiceImpl.java
package com.Ek0wraith.service;
import com.Ek0wraith.dao.UserDao;
import com.Ek0wraith.dao.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* ClassName: UserServiceImpl
* Package: com.Ek0wraith.service
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:13
* @Version 1.0
*/
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
List<User> userList = userDao.queryAll();
return userList;
}
}
UserController.java
package com.Ek0wraith.controller;
import com.Ek0wraith.dao.pojo.User;
import com.Ek0wraith.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import java.util.List;
/**
* ClassName: UserController
* Package: com.Ek0wraith.controller
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:12
* @Version 1.0
*/
@Controller
public class UserController {
@Autowired
private UserService userService;
public void findAll(){
List<User> userList = userService.findAll();
System.out.println("userList = " + userList);
}
}
3、IoC配置
application.properties
college.name=usth
4、jdbc配置
jdbc.properties
Ek0wraith.url=jdbc:mysql://localhost:3306/usermis
Ek0wraith.driver=com.mysql.cj.jdbc.Driver
Ek0wraith.username=root
Ek0wraith.password=123456
5、基于配置类方式管理组件Bean(配置+注解)
CollegeConfiguration.java
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Configuration;
/**
* ClassName: Configuration
* Package: com.Ek0wraith.config
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:30
* @Version 1.0
*/
@Configuration
@PropertySource("classpath:application.properties")
@ComponentScan("demo")
public class CollegeConfiguration {
}
将Druid连接池对象存储到IoC容器
JavaConfiguration.java
package config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* ClassName: JavaConfiguration
* Package: com.Ek0wraith.config
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:37
* @Version 1.0
*/
/**
* 第三方类进行IoC管理,无法直接使用@Component相关注解。
* 解决方案1:XML方式可以使用<bean>标签
* 解决方案2:配置类方式,可以使用方法返回值+@Bean注解
* @Bean注解用于指示方法实例化、配置和初始化要由Spring IoC容器管理的新对象。@Bean注解==<bean/>
*/
@Configuration
@PropertySource("classpath:jdbc.properties")
@ComponentScan(basePackages = {"com.Ek0wraith"})
public class JavaConfiguration {
@Value("${Ek0wraith.url}")
private String url;
@Value("${Ek0wraith.driver}")
private String driverClassName;
@Value("${Ek0wraith.username}")
private String username;
@Value("${Ek0wraith.password}")
private String password;
@Bean
public DataSource dataSource() {
//Java代码实例化
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public JdbcTemplate jdbcTemplate(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}
三、Spring—Test测试
1、导入依赖组件
<!--spring-test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>6.0.6</version>
</dependency>
2、构建元件
College.java
package demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* ClassName: College
* Package: com.Ek0wraith.demo
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:25
* @Version 1.0
*/
@Component
public class College {
@Value("${college.name:黑科技}")
private String collegeName;
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
}
spring-01.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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<context:component-scan base-package="demo"/>
</beans>
3、编写测试类
IntegrationTest1.java
package demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* ClassName: IntergrationTest1
* Package: demo
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:52
* @Version 1.0
*/
@SpringJUnitConfig(locations = {"classpath:spring-01.xml"})
public class IntegrationTest1 {
@Autowired
private College college;
@Test
public void test1(){
System.out.println("college.getCollegeName() = " +
college.getCollegeName());
}
}
IntegrationTest2.java
package demo;
import com.Ek0wraith.controller.UserController;
import config.JavaConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* ClassName: IntergrationTest2
* Package: demo
* Description:TODO
*
* @Author Ek0wraith
* @Create 2024/5/8 16:55
* @Version 1.0
*/
@SpringJUnitConfig(value = {JavaConfiguration.class})
public class IntegrationTest2 {
@Autowired
private UserController userController;
@Test
public void test2() {userController.findAll();}
}
四、执行测试,查看是否通过
1、IntegrationTest1运行结果
college.getCollegeName() = usth
Process finished with exit code 0
2、IntegrationTest2运行结果
信息: {dataSource-1} inited
userList = [User(id=1, username=Peng Yuning, password=8WvErMonB8), User(id=2, username=Takahashi Kasumi, password=YUEsievZJM), User(id=3, username=Bruce Rodriguez, password=oSKkZSv4wm), User(id=4, username=Lau Ching Wan, password=F0WfooyAy2), User(id=5, username=Lui Sze Kwan, password=Msou1bJ0vv), User(id=6, username=Ernest Crawford, password=6BZpnzERaC), User(id=7, username=Juan Castillo, password=8enHa9Ay1D), User(id=8, username=Fu Wing Kuen, password=kQbmCoKWxa), User(id=9, username=Valerie Harrison, password=MaIuoHAGHQ), User(id=10, username=Margaret Henderson, password=pBCv42yItl)]
Process finished with exit code 0
测试通过。