当前位置: 首页 > news >正文

Spring IoC容器与Bean管理

代码结构


spring01/
├── pom.xml
├── spring01.iml
└── src/├── main/│   ├── java/│   │   └── com/│   │       └── demo/│   │           ├── bean/│   │           │   ├── Demo.java│   │           │   ├── Emp1.java│   │           │   ├── Emp2.java│   │           │   └── User.java│   │           ├── dao/│   │           │   ├── UserDao.java│   │           │   └── impl/│   │           │       ├── MysqlUserDaoImpl.java│   │           │       └── OracleUserDaoImpl.java│   │           ├── factory/│   │           │   ├── Emp1Factory.java│   │           │   ├── Emp2Factory.java│   │           │   └── UserDaoFactory.java│   │           ├── service/│   │           │   ├── UserService.java│   │           │   └── impl/│   │           │       └── UserServiceImpl.java│   │           └── test/│   │               └── UserTest.java│   └── resources/│       ├── UserDao.properties│       ├── applicationContext-实例工厂创建Bean.xml│       ├── applicationContext-普通构建方法创建Bean.xml│       ├── applicationContext-静态工厂创建Bean.xml│       ├── applicationContext.xml│       └── logback.xml└── test/└── java/└── com/└── demo/├── LoggerTest.java├── TestDemo.java└── UserTest.java

该项目是一个Spring框架练习项目,主要围绕以下核心目标进行实践:

一、核心技术练习

  1. Spring IoC容器与Bean管理

    • 实现了多种Bean创建方式(普通构造方法、静态工厂、实例工厂)
    • 对应配置文件:applicationContext-*.xml系列文件
  2. 设计模式应用

    • 工厂模式:通过Emp1FactoryEmp2Factory等类实现对象创建封装
    • 接口编程:UserDao接口+Mysql/Oracle多实现类
  3. 分层架构实践

    com.demo
    ├── bean      // 数据模型层(User.java等实体类)
    ├── dao       // 数据访问层(数据库操作接口及实现)
    ├── service   // 业务逻辑层(服务接口及实现)
    └── factory   // 对象工厂层(创建Bean的工厂类)
    

二、功能模块说明

  • 数据访问:通过UserDao及实现类操作数据库,支持多数据库类型(MySQL/Oracle)
  • 依赖注入:使用Spring容器管理对象依赖关系
  • 日志系统:集成logback日志框架(logback.xml配置)
  • 配置管理:通过UserDao.properties实现配置外部化

三、测试覆盖

  • 单元测试LoggerTest(日志测试)、UserTest(用户功能测试)等测试类
  • 测试规范:遵循与主代码相同的包结构,确保测试代码可维护性

四、项目特点

  • 性质:通过多种配置文件和工厂类展示不同实现方式
  • 结构清晰:严格遵循Maven项目规范和分层架构设计
  • 可扩展性:通过接口和工厂模式预留功能扩展点

该项目适合初学者理解Spring核心概念、设计模式应用及企业级项目分层架构思想。

实体类 bean

package com.demo.bean;import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class Demo {private List<String> list;private Set<String> set;private Map<String,String> map;private Properties properties;public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Set<String> getSet() {return set;}public void setSet(Set<String> set) {this.set = set;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}
}
package com.demo.bean;public class Emp1 {public  void update1(){System.out.println("Emp1的update1()方法被调用。。。  。。。");}
}
package com.demo.bean;public class Emp2 {public  void update2(){System.out.println("Emp2的update2()方法被调用。。。  。。。");}
}
package com.demo.bean;public class User {private  Integer userId;private  String username;private  String password;public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"userId=" + userId +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}

dao层


import com.demo.bean.User;public interface UserDao {public  boolean updateUser(User user);
}import com.demo.bean.User;
import com.demo.dao.UserDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class MysqlUserDaoImpl implements UserDao {@Overridepublic boolean updateUser(User user) {Logger logger = LoggerFactory.getLogger(MysqlUserDaoImpl.class);logger.info("Mysql正在进行修改操作:updateUser();");return true;}
}import com.demo.bean.User;
import com.demo.dao.UserDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class OracleUserDaoImpl implements UserDao {@Overridepublic boolean updateUser(User user) {Logger logger = LoggerFactory.getLogger(OracleUserDaoImpl.class);logger.info("Oracle正在进行修改操作:updateUser();");return true;}
}

简单工厂模式


import com.demo.bean.Emp1;public class Emp1Factory {
public static Emp1 getInstance(){return new Emp1();
}
}package com.demo.factory;import com.demo.bean.Emp2;public class Emp2Factory {public Emp2 getInstance() {return new Emp2();}
}package com.demo.factory;import com.demo.dao.UserDao;import java.io.InputStream;
import java.util.Properties;public class UserDaoFactory {public  UserDao getInstance() {UserDao userDao = null;try {//读取属性文件Properties properties = new Properties();InputStream in = UserDaoFactory.class.getClassLoader().getResourceAsStream("UserDao.properties");properties.load(in);//通过key获取全名字符串String userDaoFullName = properties.getProperty("userDao");//通过反射获取类的实例对象userDao = (UserDao) Class.forName(userDaoFullName).newInstance();} catch (Exception e) {e.printStackTrace();}return userDao;}
}

service层

import com.demo.bean.User;public interface UserService {public boolean updateUser(User user);
}package com.demo.service.impl;import com.demo.bean.User;
import com.demo.dao.UserDao;
import com.demo.factory.UserDaoFactory;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 1.UserDao 的实现类不由UserServiceImpl来决定,而是由UserDaoFactory来决定<第一种>* 2.控制权从UserServiceImpl转移到了UserDaoFactory,这就是控制反转IOC/DI*/
@Service
public class UserServiceImpl  implements UserService{/** <第一种>UserDaoFactory userDaoFactory=new UserDaoFactory();UserDao userDao=userDaoFactory.getInstance();*/@Autowiredprivate   UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}// private UserDao userDao=new UserDaoFactory.getInstance();//报错// private UserDao userDao=new MysqlUserDaoImpl();//private UserDao userDao=new OracleUserDaoImpl();@Overridepublic boolean updateUser(User user) {return userDao.updateUser(user);}
}

测试

日志测试

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LoggerTest {@Testpublic void loggerTest() {//System.out.println(LoggerFactory.getLogger("hello"));Logger logger = LoggerFactory.getLogger(LoggerTest.class);//slf4j日志的级别logger.trace("trace");logger.debug("debug");logger.info("info");logger.warn("warn");logger.error("error");//拼接logger.info("Welcome to {} {} ", "www.51zxw.net", "go!");}}
测试 applicationContext.xml 配置文件的配置
package com.demo;import com.demo.bean.Demo;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.*;public class TestDemo {Logger logger = LoggerFactory.getLogger(LoggerTest.class);@Testpublic void testDemo() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Demo demo = (Demo) context.getBean("demo");List<String> list = demo.getList();logger.info("list----------------------");for (String s : list) {logger.info(s);}logger.info("set----------------------");Set<String> set = demo.getSet();for (String s : set) {logger.info(s);}logger.info("map----------------------");Map<String, String> map = demo.getMap();Set<String> keySet = map.keySet();Iterator<String> iterator = keySet.iterator();while (iterator.hasNext()) {String key = iterator.next();String value = map.get(key);logger.info(key + "  " + value);}logger.info("properties----------------------");Properties properties = demo.getProperties();String userId = properties.getProperty("userId");String username = properties.getProperty("username");String password = properties.getProperty("password");logger.info(userId);logger.info(username);logger.info(password);}
}
测试其他集中配置文件管理Bean
package com.demo;import com.demo.bean.Emp1;
import com.demo.bean.Emp2;
import com.demo.bean.User;
import com.demo.dao.UserDao;
import com.demo.service.UserService;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 1.从SpringIOC容器工厂中获取一个User对象* a。获取工厂BeanFactory* b。getBean()返回对象* 2.ApplicationContext是BeanFactory的子接口(实际上也是工厂)*/
public class UserTest {Logger logger = LoggerFactory.getLogger(LoggerTest.class);/*** 测试普通构造方法创建的Bean*/@Testpublic void userTest() {//获取BeanFactory的子接口,它是用来获得配置在SpringIOC容器的对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//从SpringIOC容器工厂中获取一个User对象User user = (User) context.getBean("user");if (null != user) {logger.info(user.toString());}}/*** 测试普通构造方法创建的Bean*/@Testpublic void userDaoTest() {//获取BeanFactory的子接口,它是用来获得配置在SpringIOC容器的对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-实例工厂创建Bean.xml");//从SpringIOC容器工厂中获取一个User对象UserDao userDao = (UserDao) context.getBean("userDao");if (null != userDao) {userDao.updateUser(null);}}/*** 静态工厂创建Bean*/@Testpublic void emp1Test() {//获取BeanFactory的子接口,它是用来获得配置在SpringIOC容器的对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-实例工厂创建Bean.xml");//从SpringIOC容器工厂中获取一个User对象Emp1 emp1 = (Emp1) context.getBean("emp1");if (null != emp1) {emp1.update1();}}/*** 实例工厂创建Bean*/@Testpublic void emp2Test() {//获取BeanFactory的子接口,它是用来获得配置在SpringIOC容器的对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-实例工厂创建Bean.xml");//从SpringIOC容器工厂中获取一个User对象Emp2 emp2 = (Emp2) context.getBean("emp2");if (null != emp2) {emp2.update2();}}@Testpublic void userServiceTest() {//获取BeanFactory的子接口,它是用来获得配置在SpringIOC容器的对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//从SpringIOC容器工厂中获取一个User对象UserService userService = (UserService) context.getBean("userService");if (null != userService) {userService.updateUser(null);}}
}
测试第一种被UserDaoFactory来决定实现的方式

要解开注解,UserServiceImpl代码改为

    UserDaoFactory userDaoFactory=new UserDaoFactory();UserDao userDao=userDaoFactory.getInstance();
//    @Autowired
//    private  UserDao userDao;
// 其余不变
package com.demo.test;import com.demo.bean.User;
import com.demo.service.UserService;
import com.demo.service.impl.UserServiceImpl;public class UserTest {public static void main(String[] args) {UserService userService=new UserServiceImpl();User user=new User();userService.updateUser(user);}
}

配置文件

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"><!--    创建对象--><bean id="user" class="com.demo.bean.User"><!--  为对象注入属性值   --><property name="userId" value="1"></property><property name="username" value="张三"></property><property name="password" value="123456"></property></bean><!-- 1.创建属性对象MysqlUserDaoImpl(如果是Besn类型)a.必须添加setter()方法注入属性;b.通过构造方法注入属性2.创建userService--><bean id="userDao" class="com.demo.dao.impl.MysqlUserDaoImpl"></bean><bean id="userService" class="com.demo.service.impl.UserServiceImpl"><!--    ref是通过引用userDao,然后找到实现类    --><property name="userDao" ref="userDao"></property></bean><!--集合属性的注入:list:添加list节点,然后如果集合中的数据是引用数据类型需要使用ref节点,如果是基本数据类型用valueset:添加set节点,然后如果集合中的数据是引用数据类型需要使用ref节点,如果是基本数据类型用valuemap:添加map节点,由于map中储存的是key和value键值对,需要添加一个entry节点对应key,如果数据是引用数据类型需要使用ref节点,如果是基本数据类型用value对应value,如果数据是引用数据类型需要使用ref节点,如果是基本数据类型用valueproperties:添加props节点,然后在添加prop--><bean id="demo" class="com.demo.bean.Demo"><property name="list"><list><value>乔丹</value><value>科比</value><!--<bean>ref的配置</bean>--><!--                <ref>如果是类类型,或者引用数据类型,需要ref</ref>--></list></property><property name="set"><set><value>姚明</value><value>易建联</value><value>王致和</value></set></property><property name="map"><map><entry><key><value>001</value></key><value>篮球</value></entry><entry><key><value>002</value></key><value>足球</value></entry><entry><key><value>003</value></key><value>乒乓球</value></entry></map></property><property name="properties"><props><prop key="userId">1</prop><prop key="username">test</prop><prop key="password">123456</prop></props></property></bean>
</beans>

applicationContext-实例工厂创建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"><!--采用实例工厂创建Bean1.创建Emp22.创建Emp2Factory静态工厂3.编写配置文件,注意和普通工厂对比,多两个属性配置factory-method="静态方法名"factory-bean属性的配置总结:相比普通构造方法创建Bean而言稍微麻烦一些,所以很少用--><bean id="emp2Factory" class="com.demo.factory.Emp2Factory"></bean><bean id="emp2" factory-bean="emp2Factory" factory-method="getInstance"></bean>
</beans>

applicationContext-普通构建方法创建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"><!--    Spring容器--><!--采用普通的构造方法来创建Bean--><bean id="userService" class="com.demo.service.impl.UserServiceImpl"></bean><bean id="userDao" class="com.demo.dao.impl.MysqlUserDaoImpl"></bean><!-- 采用普通的构建方法创建User--><bean id="user" class="com.demo.bean.User"></bean></beans>

applicationContext-静态工厂创建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
1.创建Emp1
2.创建Emp1Factory静态工厂
3.编写配置文件,注意和普通工厂对比,多一个属性配置factory-method="静态方法名"总结:相比普通构造方法创建Bean而言稍微麻烦一些,所以很少用
-->
<bean id="emp1" class="com.demo.factory.Emp1Factory" factory-method="getInstance"></bean></beans>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--输出日志到控制台 appender追加--><appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"><!--负责把事件转成字符串,格式化日志信息的输出--><layout><pattern><!--%p是日志优先级%d是日期,%msg是日志消息%n换行-->[%p]%d-%msg%n</pattern></layout></appender><appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><onMatch>DENY</onMatch></filter><encoder><pattern>[%p]%d-%msg%n</pattern></encoder><!-- 指定文件的输出位置--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern></fileNamePattern></rollingPolicy></appender>
<!-- 控制台可以输出的级别   --><root level="info"><appender-ref ref="consoleLog"></appender-ref><appender-ref ref="fileLog"></appender-ref></root>
</configuration>

UserDao.properties

userDao=com.demo.dao.impl.OracleUserDaoImpl
http://www.lryc.cn/news/610009.html

相关文章:

  • GPTs——定制的小型智能体
  • 白杨SEO:百度搜索开放平台发布AI计划是什么?MCP网站红利来了?顺带说说其它
  • [Oracle] || 连接运算符
  • 关于如何自定义vscode(wsl连接linux)终端路径文件夹文件名字颜色的步骤:
  • 【PHP】获取图片的主要颜色值RGB值
  • 【Django】-3- 处理HTTP响应
  • Django 性能优化详解:从数据库到缓存,打造高效 Web 应用
  • CNN卷积神经网络之MobileNet和ResNet(五)
  • AWS Lambda Function 全解:无服务器计算
  • CAD格式转换器HOOPS Exchange:全方位支持HOOPS系列产品
  • Webpack 搭建 Vue3 脚手架详细步骤
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现人脸面部表情的追踪识别(C#代码UI界面版)
  • [3D数据存储] Archive (File Container) | 创建/写入/读取 | 存储格式HDF5
  • pyqt5-tools/pyqt6-tools 安装失败,解决办法
  • app-1
  • Spring P1 | 创建你的第一个Spring MVC项目(IDEA图文详解版,社区版专业版都有~)
  • 理解 Agent 的基本概念与功能
  • 正点原子STM32MP257开发板移植ubuntu24.04根文件系统(带桌面版)
  • RTSP/RTMP播放器超低延迟实战:无人机远控视觉链路的工程实践
  • [特殊字符]️ 整个键盘控制无人机系统框架
  • 链表与数组面试常见问题详解与实现
  • 分布式存储性能跃迁指南:RoCE无损网络设计与优化
  • mysql远程登陆失败
  • DC-Mamba:一种用于热红外无人机图像盲超分辨率的退化感知跨模态框架
  • 正则表达式在js中的应用
  • Hadoop MapReduce 3.3.4 讲解~
  • Prometheus-3--Prometheus是怎么抓取Java应用,Redis中间件,服务器环境的指标的?
  • 超详细:2026年博士申请时间线
  • 【Redis】安装Redis,通用命令
  • Redis键值对中值的数据结构