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-實例工廠創(chuàng)建Bean.xml │ ├── applicationContext-普通構建方法創(chuàng)建Bean.xml │ ├── applicationContext-靜態(tài)工廠創(chuàng)建Bean.xml │ ├── applicationContext.xml │ └── logback.xml └── test/ └── java/ └── com/ └── demo/ ├── LoggerTest.java ├── TestDemo.java └── UserTest.java
該項目是一個Spring框架練習項目,主要圍繞以下核心目標進行實踐:
一、核心技術練習
Spring IoC容器與Bean管理
- 實現(xiàn)了多種Bean創(chuàng)建方式(普通構造方法、靜態(tài)工廠、實例工廠)
- 對應配置文件:
applicationContext-*.xml
系列文件
設計模式應用
- 工廠模式:通過
Emp1Factory
、Emp2Factory
等類實現(xiàn)對象創(chuàng)建封裝 - 接口編程:
UserDao
接口+Mysql/Oracle
多實現(xiàn)類
- 工廠模式:通過
分層架構實踐
com.demo ├── bean // 數(shù)據(jù)模型層(User.java等實體類) ├── dao // 數(shù)據(jù)訪問層(數(shù)據(jù)庫操作接口及實現(xiàn)) ├── service // 業(yè)務邏輯層(服務接口及實現(xiàn)) └── factory // 對象工廠層(創(chuàng)建Bean的工廠類)
二、功能模塊說明
- 數(shù)據(jù)訪問:通過
UserDao
及實現(xiàn)類操作數(shù)據(jù)庫,支持多數(shù)據(jù)庫類型(MySQL/Oracle) - 依賴注入:使用Spring容器管理對象依賴關系
- 日志系統(tǒng):集成logback日志框架(
logback.xml
配置) - 配置管理:通過
UserDao.properties
實現(xiàn)配置外部化
三、測試覆蓋
- 單元測試:
LoggerTest
(日志測試)、UserTest
(用戶功能測試)等測試類 - 測試規(guī)范:遵循與主代碼相同的包結構,確保測試代碼可維護性
四、項目特點
- 性質:通過多種配置文件和工廠類展示不同實現(xiàn)方式
- 結構清晰:嚴格遵循Maven項目規(guī)范和分層架構設計
- 可擴展性:通過接口和工廠模式預留功能擴展點
該項目適合初學者理解Spring核心概念、設計模式應用及企業(yè)級項目分層架構思想。
實體類 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; } @Override public 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 { @Override public 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 { @Override public 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 的實現(xiàn)類不由UserServiceImpl來決定,而是由UserDaoFactory來決定<第一種> * 2.控制權從UserServiceImpl轉移到了UserDaoFactory,這就是控制反轉IOC/DI */ @Service public class UserServiceImpl implements UserService{ /** <第一種> UserDaoFactory userDaoFactory=new UserDaoFactory(); UserDao userDao=userDaoFactory.getInstance();*/ @Autowired private 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(); @Override public boolean updateUser(User user) { return userDao.updateUser(user); } }
測試
日志測試
import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoggerTest { @Test public 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); @Test public 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); /** * 測試普通構造方法創(chuàng)建的Bean */ @Test public 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()); } } /** * 測試普通構造方法創(chuàng)建的Bean */ @Test public void userDaoTest() { //獲取BeanFactory的子接口,它是用來獲得配置在SpringIOC容器的對象 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-實例工廠創(chuàng)建Bean.xml"); //從SpringIOC容器工廠中獲取一個User對象 UserDao userDao = (UserDao) context.getBean("userDao"); if (null != userDao) { userDao.updateUser(null); } } /** * 靜態(tài)工廠創(chuàng)建Bean */ @Test public void emp1Test() { //獲取BeanFactory的子接口,它是用來獲得配置在SpringIOC容器的對象 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-實例工廠創(chuàng)建Bean.xml"); //從SpringIOC容器工廠中獲取一個User對象 Emp1 emp1 = (Emp1) context.getBean("emp1"); if (null != emp1) { emp1.update1(); } } /** * 實例工廠創(chuàng)建Bean */ @Test public void emp2Test() { //獲取BeanFactory的子接口,它是用來獲得配置在SpringIOC容器的對象 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-實例工廠創(chuàng)建Bean.xml"); //從SpringIOC容器工廠中獲取一個User對象 Emp2 emp2 = (Emp2) context.getBean("emp2"); if (null != emp2) { emp2.update2(); } } @Test public 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來決定實現(xiàn)的方式
要解開注解,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"> <!-- 創(chuàng)建對象--> <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.創(chuàng)建屬性對象MysqlUserDaoImpl(如果是Besn類型) a.必須添加setter()方法注入屬性; b.通過構造方法注入屬性 2.創(chuàng)建userService --> <bean id="userDao" class="com.demo.dao.impl.MysqlUserDaoImpl"></bean> <bean id="userService" class="com.demo.service.impl.UserServiceImpl"> <!-- ref是通過引用userDao,然后找到實現(xiàn)類 --> <property name="userDao" ref="userDao"></property> </bean> <!-- 集合屬性的注入: list:添加list節(jié)點,然后如果集合中的數(shù)據(jù)是引用數(shù)據(jù)類型需要使用ref節(jié)點,如果是基本數(shù)據(jù)類型用value set:添加set節(jié)點,然后如果集合中的數(shù)據(jù)是引用數(shù)據(jù)類型需要使用ref節(jié)點,如果是基本數(shù)據(jù)類型用value map:添加map節(jié)點,由于map中儲存的是key和value鍵值對,需要添加一個entry節(jié)點 對應key,如果數(shù)據(jù)是引用數(shù)據(jù)類型需要使用ref節(jié)點,如果是基本數(shù)據(jù)類型用value 對應value,如果數(shù)據(jù)是引用數(shù)據(jù)類型需要使用ref節(jié)點,如果是基本數(shù)據(jù)類型用value properties:添加props節(jié)點,然后在添加prop --> <bean id="demo" class="com.demo.bean.Demo"> <property name="list"> <list> <value>喬丹</value> <value>科比</value> <!--<bean>ref的配置</bean>--> <!-- <ref>如果是類類型,或者引用數(shù)據(jù)類型,需要ref</ref>--> </list> </property> <property name="set"> <set> <value>姚明</value> <value>易建聯(lián)</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-實例工廠創(chuàng)建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"> <!--采用實例工廠創(chuàng)建Bean 1.創(chuàng)建Emp2 2.創(chuàng)建Emp2Factory靜態(tài)工廠 3.編寫配置文件,注意和普通工廠對比,多兩個屬性配置factory-method="靜態(tài)方法名" factory-bean屬性的配置 總結:相比普通構造方法創(chuàng)建Bean而言稍微麻煩一些,所以很少用 --> <bean id="emp2Factory" class="com.demo.factory.Emp2Factory"></bean> <bean id="emp2" factory-bean="emp2Factory" factory-method="getInstance"></bean> </beans>
applicationContext-普通構建方法創(chuàng)建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容器--> <!--采用普通的構造方法來創(chuàng)建Bean--> <bean id="userService" class="com.demo.service.impl.UserServiceImpl"></bean> <bean id="userDao" class="com.demo.dao.impl.MysqlUserDaoImpl"></bean> <!-- 采用普通的構建方法創(chuàng)建User--> <bean id="user" class="com.demo.bean.User"></bean> </beans>
applicationContext-靜態(tài)工廠創(chuàng)建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"> <!--采用靜態(tài)工廠創(chuàng)建Bean 1.創(chuàng)建Emp1 2.創(chuàng)建Emp1Factory靜態(tài)工廠 3.編寫配置文件,注意和普通工廠對比,多一個屬性配置factory-method="靜態(tài)方法名" 總結:相比普通構造方法創(chuàng)建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是日志優(yōu)先級%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
總結
到此這篇關于Spring IoC容器與Bean管理的文章就介紹到這了,更多相關Spring IoC容器與Bean管理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
HttpServletRequest對象簡介_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了HttpServletRequest對象簡介的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07Jenkins中自動化部署Spring?Boot項目的全過程
這篇文章主要介紹了如何使用Jenkins從Git倉庫拉取SpringBoot項目并進行自動化部署,通過配置Jenkins任務,實現(xiàn)項目的構建、鏡像構建和容器運行,確保項目在更新時自動部署,需要的朋友可以參考下2025-01-01Java實現(xiàn)Consul/Nacos根據(jù)GPU型號、顯存余量執(zhí)行負載均衡的步驟詳解
這篇文章主要介紹了Java實現(xiàn)Consul/Nacos根據(jù)GPU型號、顯存余量執(zhí)行負載均衡的步驟詳解,本文分步驟結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2025-04-04Spring Boot 2.2 正式發(fā)布,大幅性能提升 + Java 13 支持
隨著 Spring Framework 5.2.0 成功發(fā)布之后,Spring Boot 2.2 也緊跟其后,發(fā)布了第一個版本:2.2.0。下面就來一起來看看這個版本都更新了些什么值得我們關注的內容2019-10-10