模仿spring的核心容器創建單例對象
項目結構
配置文件
-
bean.properties
accountService = com.xiaoge.service.impl.AccountServiceImpl accountDao = com.xiaoge.dao.impl.AccountDaoImpl
持久層接口
-
AccountDao
package com.xiaoge.dao; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:31 * @Description: TODO */ public interface AccountDao { public void saveAccount(); }
持久層實現類
-
AccountDaoImpl
package com.xiaoge.dao.impl; import com.xiaoge.dao.AccountDao; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:31 * @Description: TODO */ public class AccountDaoImpl implements AccountDao { public void saveAccount() { System.out.println("保存成功!"); } }
業務層接口
-
AccountService
package com.xiaoge.service; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:26 * @Description: 賬戶業務層接口 */ public interface AccountService { /** * 模擬保存 */ public void saveAccount(); }
業務層實現類
-
AccountServiceImpl
package com.xiaoge.service.impl; import com.xiaoge.dao.AccountDao; import com.xiaoge.factory.BeanFactory; import com.xiaoge.service.AccountService; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:28 * @Description: 賬戶業務層實現類 */ public class AccountServiceImpl implements AccountService { private AccountDao accountDao = (AccountDao)BeanFactory.getBean("accountDao"); public void saveAccount() { accountDao.saveAccount(); } }
工廠
-
BeanFactory
package com.xiaoge.factory; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:54 * @Description: TODO * * Bean, 在計算機英語中, 有可重用組件的含義. * JavaBean: 用java語言編寫的可重用組件. * javabean > 實體類 * * 它就是創建我們的service和dao對象的. * * 第一個: 需要一個配置文件來配置我們的service和dao * 配置的內容: 唯一標識 = 全限定類名 (key = value) * * 第二個: 通過讀取配置文件中配置的內容, 反射創建對象. * * 配置文件可以是xml也可以是properties */ public class BeanFactory { private static Properties prop = null; // 定義一個map, 用於存放我們要創建的對象, 我們把它稱職爲容器 private static Map<String, Object> beans; // 注意: 靜態變量, 跟實例沒關係, 靜態變量只能出現在靜態方法中, 值是會根據靜態方法修改它而修改的 // 而成員變量, 是根據實例走的, 每創建一個實例, 成員變量就會被初始化一遍 // 在類加載的init階段,類的類構造器中會收集所有的static塊和字段並執行,static塊只執行一次,由JVM保證其只執行一次。 // 加載順序: 一般順序:靜態塊(靜態變量)——>成員變量——>構造方法——>靜態方法 static { try { InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); // 實例化對象 prop = new Properties(); prop.load(is); // 實例化容器 beans = new HashMap<String, Object>(); // 獲取配置文件中的所有key Enumeration keys = prop.keys(); // 遍歷keys while(keys.hasMoreElements()) { // 獲取每一個key String key = (String)keys.nextElement(); // 獲取每個key對應的權限定類名 String ClassPath = prop.getProperty(key); // 將全限定類名加載進內存, 並創建對象 Object value = Class.forName(ClassPath).newInstance(); // 將數據添加進map beans.put(key, value); } } catch (IOException e) { throw new ExceptionInInitializerError("初始化properties失敗!"); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 根據Bean名稱創建Bean對象 (單例) * @param beanName * @return */ public static Object getBean(String beanName) { Object bean = null; // 獲取map中對應鍵的值, 並且返回, 當map集合中沒有該鍵, 直接拋出異常 bean = beans.get(beanName); System.out.println(bean); return bean; } /** * 根據Bean名稱獲取Bean對象 (多例) * @param beanName * @return public static Object getBean(String beanName) { Object bean = null; String name = prop.getProperty(beanName); // 把權限定類名加載進內存, 並且創建一個實例化對象 try { bean = Class.forName(name).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return bean; } */ }
main
-
Client
package com.xiaoge.ui; import com.xiaoge.factory.BeanFactory; import com.xiaoge.service.AccountService; /** * @Author: 瀟哥 * @DateTime: 2020/3/19 下午7:35 * @Description: 模擬表現層, 調用業務層 */ public class Client { public static void main(String[] args) { // AccountService accountService = new AccountServiceImpl(); for (int i = 0; i < 5; i++) { AccountService accountService = (AccountService)BeanFactory.getBean("accountService"); accountService.saveAccount(); } // 運行結果 com.xiaoge.dao.impl.AccountDaoImpl@610455d6 com.xiaoge.service.impl.AccountServiceImpl@511d50c0 保存成功! com.xiaoge.service.impl.AccountServiceImpl@511d50c0 保存成功! com.xiaoge.service.impl.AccountServiceImpl@511d50c0 保存成功! com.xiaoge.service.impl.AccountServiceImpl@511d50c0 保存成功! com.xiaoge.service.impl.AccountServiceImpl@511d50c0 保存成功! } }