中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)項(xiàng)目報價友情鏈接網(wǎng)站大全

網(wǎng)站建設(shè)項(xiàng)目報價,友情鏈接網(wǎng)站大全,播州區(qū)建設(shè)局網(wǎng)站,北京百度推廣優(yōu)化公司繼續(xù)整理記錄這段時間來的收獲,詳細(xì)代碼可在我的Gitee倉庫Java設(shè)計模式克隆下載學(xué)習(xí)使用! 7.4 自定義Spring IOC 創(chuàng)建新模塊,結(jié)構(gòu)如圖![[Pasted image 20230210173222.png]] 7.4.1 定義bean相關(guān)POJO類 7.4.1.1 定義propertyValue類 /** …

繼續(xù)整理記錄這段時間來的收獲,詳細(xì)代碼可在我的Gitee倉庫Java設(shè)計模式克隆下載學(xué)習(xí)使用!

7.4 自定義Spring IOC

創(chuàng)建新模塊,結(jié)構(gòu)如圖![[Pasted image 20230210173222.png]]

7.4.1 定義bean相關(guān)POJO類

7.4.1.1 定義propertyValue類

/**  * @Author:Phil  * @ClassName: PropertyValue  * @Description:  * 用來封裝bean標(biāo)簽下的property標(biāo)簽屬性  * name屬性  * ref屬性  * value屬性:給基本數(shù)據(jù)類型及String類型賦值  * @Date 2023/2/8 21:45  * @Version: 1.0  **/public class propertyValue {  private String name;  private String ref;  private String value;  public propertyValue() {  }  public propertyValue(String name, String ref, String value) {  this.name = name;  this.ref = ref;  this.value = value;  }  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public String getRef() {  return ref;  }  public void setRef(String ref) {  this.ref = ref;  }  public String getValue() {  return value;  }  public void setValue(String value) {  this.value = value;  }  
}

7.4.1.2 定義MultiplePropertyValue類

一個bean 標(biāo)簽可以有多個property子標(biāo)簽,故用multiplePropertyValue類來存儲PropertyValue對象

public class MultiplePropertyValues implements Iterable<PropertyValue>{  
//    定義list集合對象,用來存儲PropertyValue對象  private final List<PropertyValue> propertyValueList;  public MultiplePropertyValues() {  this.propertyValueList = new ArrayList<PropertyValue> ();  }  public MultiplePropertyValues(List<PropertyValue> propertyValueList) {  if(propertyValueList == null)  this.propertyValueList = new ArrayList<PropertyValue>();  else            this.propertyValueList = propertyValueList;  }  
//    獲取所有propertyValue對象,以數(shù)組形式返回  public PropertyValue[] getPropertyValues(){  return propertyValueList.toArray(new PropertyValue[0]);  }  
//    根據(jù)name屬性值返回對應(yīng)PropertyValue對象  public PropertyValue getPropertyValues(String propertyName){  
//        遍歷集合返回  for (PropertyValue propertyValue : propertyValueList) {  if(propertyValue.getName().equals(propertyName))  return propertyValue;  }  return null;  }  
//    判斷集合是否為空  public boolean isEmpty(){  return propertyValueList.isEmpty();  }  
//    添加PropertyValue對象  public MultiplePropertyValues addPropertyValue(PropertyValue pv){  
//        若有則進(jìn)行覆蓋  for (int i = 0; i < propertyValueList.size(); i++) {  if(propertyValueList.get(i).getName().equals(pv.getName())){  propertyValueList.set(i,pv);  return this;//目的是鏈?zhǔn)骄幊? }  }  
//            添加新的  this.propertyValueList.add(pv);  return this;    }  
//    判斷是否有指定name的PropertyValue對象  public boolean contains(String propertyName){  return getPropertyValues(propertyName) != null;  }  
//    獲取迭代器對象  @Override  public Iterator<PropertyValue> iterator() {  return propertyValueList.iterator();  }  
}

7.1.4.3 BeanDefinition類

BeanDefinition類用來封裝bean信息,主要包含id(bean 名稱),class(bean全類名)及子標(biāo)簽property對象數(shù)據(jù)

public class BeanDefinition {  private String id;  private String className;  private MultiplePropertyValues multiplePropertyValues;  public BeanDefinition() {  multiplePropertyValues = new MultiplePropertyValues();  }  public String getId() {  return id;  }  public void setId(String id) {  this.id = id;  }  public String getClassName() {  return className;  }  public void setClassName(String className) {  this.className = className;  }  public MultiplePropertyValues getMultiplePropertyValues() {  return multiplePropertyValues;  }  public void setMultiplePropertyValues(MultiplePropertyValues multiplePropertyValues) {  this.multiplePropertyValues = multiplePropertyValues;  }  
}

7.4.2 定義注冊表類

7.4.2.1 定義BeanDefinitionRegistry接口

BeanDefinitionRegistry接口定義了注冊表相關(guān)操作,定義如下功能:

  • 注冊BeanDefinition對象到注冊表中
  • 根據(jù)名稱從注冊表中獲取后去BeanDefinition對象
  • 從注冊表中刪除指定名稱的BeanDefinition對象
  • 判斷注冊表中是否包含指定名稱的BeanDefinition對象
  • 獲取注冊表中BeanDefinition對象個數(shù)
  • 獲取注冊表中所有的Bean
public interface BeanDefinitionRegistry {  //往注冊表中注冊bean  void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) ;  //從注冊表刪掉指定名稱bean  void removeBeanDefinition(String beanName) throws Exception;  //獲取指定名稱bean  BeanDefinition getBeanDefinition(String beanName) throws Exception;  //判斷是否包含指定名稱bean  boolean containsBeanDefinition(String beanName);  //獲取所有bean  String[] getBeanDefinitionNames();  int getBeanDefinitionCount();  boolean isBeanNameInUse(String var1);  
}

7.4.2.2 SimpleBeanDefinitionRegistry類

public class SimpleBeanDefinitionRegistry implements BeanDefinitionRegistry{  
//    創(chuàng)建容器,用于存儲  Map<String,BeanDefinition> beanDefinitionMap = new HashMap<String,BeanDefinition>();  @Override  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {  beanDefinitionMap.put(beanName,beanDefinition);  }  @Override  public void removeBeanDefinition(String beanName) throws Exception {  beanDefinitionMap.remove(beanName);  }  @Override  public BeanDefinition getBeanDefinition(String beanName) throws Exception {  return beanDefinitionMap.get(beanName);  }  @Override  public boolean containsBeanDefinition(String beanName) {  return beanDefinitionMap.containsKey(beanName);  }  @Override  public String[] getBeanDefinitionNames() {  return beanDefinitionMap.keySet().toArray(new String[0]);  }  @Override  public int getBeanDefinitionCount() {  return beanDefinitionMap.size();  }  @Override  public boolean isBeanNameInUse(String var1) {  return beanDefinitionMap.containsKey(var1);  }  
}

7.4.3 定義解析器類

7.4.3.1 BeanDefinitionReader接口

BeanDefinitionReader用來解析配置文件并在注冊表中注冊bean的信息,定義了兩規(guī)范:

  • 獲取注冊表功能,讓外界可通過該對象獲取注冊表對象
  • 加載配置文件,并注冊bean數(shù)據(jù)
public interface BeanDefinitionReader{//獲取注冊表對象BeanDefinitionRegistry getRegistry();//加載配置文件斌在注冊表中進(jìn)行注冊void loadBeanDefinitions(String configuration);
}

7.4.3.2 XmlBeanDefinitionReader類

XmlBeanDefinitionReader類是專門來解析xml配置文件,實(shí)現(xiàn)了BeanDefinitionReader接口的兩個功能。

public class XmlBeanDefinitionReader implements BeanDefinitionReader {  
//    聲明注冊表對象  private BeanDefinitionRegistry registry;  public XmlBeanDefinitionReader() {  this.registry = new SimpleBeanDefinitionRegistry();  }  @Override  public BeanDefinitionRegistry getRegistry() {  return registry;  }  @Override  public void loadBeanDefinitions(String configuration) throws Exception{  
//        使用dom4j進(jìn)行xml配置文件的解析  SAXReader saxReader = new SAXReader();  
//        后去類路徑下的配置文件  InputStream resourceAsStream = XmlBeanDefinitionReader.class.getClassLoader().getResourceAsStream(configuration);  Document document = saxReader.read(resourceAsStream);  
//        根據(jù)Document對象獲取根標(biāo)簽對象(beans)  Element rootElement = document.getRootElement();  
//       獲取根標(biāo)簽下所有的bean標(biāo)簽對象  List<Element> elements = rootElement.elements("bean");  
//        遍歷集合  for (Element element : elements) {  
//            獲取id屬性  String id = element.attributeValue("id");  
//            獲取className  String className = element.attributeValue("class");  
//          將id和className封裝到BeanDefinition對象中  
//          創(chuàng)建BeanDefinition對象  BeanDefinition beanDefinition = new BeanDefinition();  beanDefinition.setId(id);  beanDefinition.setClassName(className);  
//            創(chuàng)建MultiplePropertyValue對象  MultiplePropertyValues multiplePropertyValues = new MultiplePropertyValues();  
//          獲取bean標(biāo)簽下的所有property標(biāo)簽對象  List<Element> propertyElements = element.elements("property");  for (Element propertyElement : propertyElements) {  String name = propertyElement.attributeValue("name");  String ref = propertyElement.attributeValue("ref");  String value = propertyElement.attributeValue("value");  PropertyValue propertyValue = new PropertyValue(name, ref, value);  multiplePropertyValues.addPropertyValue(propertyValue);  }  
//            將multiplePropertyValues封裝到BeanDefinition中  beanDefinition.setMultiplePropertyValues(multiplePropertyValues);  
//            將BeanDefinition注冊到注冊表中  registry.registerBeanDefinition(id,beanDefinition);  }  }  
}

7.4.4 容器相關(guān)類

7.4.4.1 BeanFactory接口

該接口定義IOC容器的統(tǒng)一規(guī)范即獲取bean對象

public interface BeanFactory{//根據(jù)bean對象的名稱獲取bean對象Object getBean(String name) throws Exception;//根據(jù)bean對象的名稱獲取bean對象,并進(jìn)行類型轉(zhuǎn)換<T> T getBean(String name,Class<? extends T> clazz) throws Exception;
}

7.4.4.2 ApplicationContext接口

該接口的子實(shí)現(xiàn)類對bean 對象的創(chuàng)建都是非延時的,所以該接口定義refresh方法,主要有兩功能:

  • 加載配置文件
  • 根據(jù)注冊表中BeanDefinition對象封裝的數(shù)據(jù)進(jìn)行bean對象的創(chuàng)建
public interface ApplicationContext extends BeanFactory{  void refresh()throws Exception;  
}

7.4.4.3 AbstractApplicationContext接口

  • 作為ApplicationContext接口的子類,故該類是非延時加載,故需要在該類中定義Map集合,作為bean對象存儲容器
  • 聲明BeanDefinition類型變量,用來進(jìn)行xml配置文件解析,符合單一職責(zé)原則
  • BeanDefinition類型對象創(chuàng)建交由子類實(shí)現(xiàn),子類明確創(chuàng)建BeanDefinitionReader
public abstract class AbstractApplicationContext implements ApplicationContext {  
//    聲明解析器對象  protected BeanDefinitionReader beanDefinitionReader;  
//   存儲bean容器,key存儲的bean的id,value是bean對象  protected Map<String,Object> singletonObject = new HashMap<String,Object>();;  
//    存儲配置文件路徑  String configLocation;  public void refresh() throws Exception{  
//   加載BeanDefinition  beanDefinitionReader.loadBeanDefinitions(configLocation);  
//       初始化bean  finishBeanInitialization();  }  public void finishBeanInitialization() throws Exception{  
//       獲取注冊表對象  BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry();  
//        獲取BeanDefinition對象  String [] beanNames = registry.getBeanDefinitionNames();  
//        初始化bean  for (String beanName : beanNames) {  getBean(beanName);  }  }  
}

7.4.4.4 ClassPathXmlApplicationContext接口

該類主要是加載類路徑下的配置文件,并進(jìn)行bean對象的創(chuàng)建,主要有以下功能:

  • 在構(gòu)造方法中,創(chuàng)建BeanDefinitionReader對象
  • 在構(gòu)造方法中,調(diào)用refresh方法,用于進(jìn)行配置文件加載,創(chuàng)建bean對象并存儲到容器中
  • 重寫父類中的getBean方法,并實(shí)現(xiàn)依賴注入
public class ClassPathXmlApplicationContext extends AbstractApplicationContext{  public ClassPathXmlApplicationContext(String configLocation){  this.configLocation = configLocation;  
//        構(gòu)建解析器對象  beanDefinitionReader = new XmlBeanDefinitionReader();  try {  this.refresh();  }catch (Exception exception){  exception.printStackTrace();  }  }  
//    根據(jù)bean對象的名稱獲取bean對象  @Override  public Object getBean(String name) throws Exception {  
//        判斷對象容器中是否包含指定bean對象,若包含則返回,否則創(chuàng)建  Object object = singletonObject.get(name);  if(object != null)  return object;  
//        獲取BeanDefinition對象  BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry();  BeanDefinition beanDefinition = registry.getBeanDefinition(name);  
//       獲取bean信息中的className  String className = beanDefinition.getClassName();  
//        通過反射獲取對象  Class<?> clazz = Class.forName(className);  Object instance = clazz.newInstance();  
//        進(jìn)行依賴注入操作  MultiplePropertyValues multiplePropertyValues = beanDefinition.getMultiplePropertyValues();  for (PropertyValue propertyValue : multiplePropertyValues) {  
//            獲取name屬性值  String propertyValueName = propertyValue.getName();  
//            獲取value值  String value = propertyValue.getValue();  
//            獲取ref值  String ref = propertyValue.getRef();  if(ref != null && !"".equals(ref)){  
//                獲取依賴的對象  Object bean = getBean(ref);  
//                拼接方法名  String setterMethodByField = StringUtils.getSetterMethodByField(propertyValueName);  
//                獲取所有方法  Method[] methods = clazz.getMethods();  for (Method method : methods) {  if(method.getName().equals(setterMethodByField))  
//                        執(zhí)行setter方法  method.invoke(instance,bean);  }  }  if(value != null && !"".equals(value)){  
//                拼接方法名  String methodName = StringUtils.getSetterMethodByField(propertyValueName);  
//                獲取method對象  Method method = clazz.getMethod(methodName, String.class);  method.invoke(instance, value);  }  }  
//        在返回instance對象之前,將該對象存儲到map容器中  singletonObject.put(name,instance);  return instance;  }  @Override  public <T> T getBean(String name, Class<? extends T> clazz) throws Exception {  Object bean = getBean(name);  if(bean == null)  return null;  return clazz.cast(bean);  }  
}

7.4.4.5 測試

將前文回顧Spring框架項(xiàng)目中的pom文件的spring-context依賴換為上述新建項(xiàng)目依賴,如圖
![[Pasted image 20230210173346.png]]
運(yùn)行后如圖
![[Pasted image 20230210173447.png]]

7.4.5 總結(jié)

7.4.5.1 使用到的設(shè)計模式

  • 工廠模式:工廠模式+ 配置文件
  • 單例模式。Spring IOC管理的bean都是單例的,此處單例不是通過構(gòu)造器進(jìn)行單例構(gòu)建,且框架對每個bean只創(chuàng)建一個對象。
  • 模板方法模式。AbstractApplicationContext類中的finishInitialization方法調(diào)用getBean方法,因?yàn)間etBean實(shí)現(xiàn)和環(huán)境有關(guān)。
  • 迭代器模式。其中MultiplePropertyValyes類使用了迭代器模式,因?yàn)榇祟惔鎯Σ⒐芾鞵ropertyValue對象,也屬于一個容器。
  • 還使用了很多設(shè)計模式,如AOP使用到了代理模式,選擇JDK代理或CGLIB代理使用了策略模式,還有適配器模式,裝飾者模式,觀察者模式等。

7.4.5.2 符合大部分設(shè)計原則

7.4.5.3 整個設(shè)計和Spring設(shè)計還有一定出入

Spring框架底層是很復(fù)雜的,進(jìn)行了很深入的封裝,并對外提供了很好的擴(kuò)展性,自定義Spring IOC容器有兩目的:

  • 了解Spring底層對對象的大體管理機(jī)制
  • 了解設(shè)計模式在具體開發(fā)中的使用
  • 以后學(xué)習(xí)Spring源碼,通過該案例實(shí)現(xiàn),可以降低Spring學(xué)習(xí)入門成本
http://www.risenshineclean.com/news/9281.html

相關(guān)文章:

  • 孝義網(wǎng)站建設(shè)近兩年網(wǎng)絡(luò)營銷成功案例
  • 網(wǎng)頁版qq郵箱怎么發(fā)文件北京seo加盟
  • 網(wǎng)站目錄不能訪問百度站長工具網(wǎng)站提交
  • wordpress前臺出現(xiàn)舊版文件夾廣州抖音seo
  • 優(yōu)酷網(wǎng)站誰做的seo智能優(yōu)化公司
  • 做招聘網(wǎng)站怎么樣寧波網(wǎng)站seo診斷工具
  • 工會網(wǎng)站建設(shè)管理工作總結(jié)軟文營銷范文
  • 企業(yè)logo圖片上海seo外包
  • 做網(wǎng)站之前的工作網(wǎng)站排名查詢工具有哪些
  • 電商網(wǎng)站的建設(shè)與維護(hù)云南網(wǎng)絡(luò)推廣公司排名
  • 網(wǎng)站建設(shè)公司彩鈴廣告公司招聘
  • 如何通過axure做網(wǎng)站抖音推廣引流平臺
  • 字體大全seo職業(yè)培訓(xùn)學(xué)校
  • 咸陽北京網(wǎng)站建設(shè)推廣普通話的重要意義
  • 臺州市臨海建設(shè)局網(wǎng)站友情鏈接qq群
  • wordpress 360字體大小seo網(wǎng)絡(luò)推廣技術(shù)
  • 綿陽市中醫(yī)醫(yī)院網(wǎng)站建設(shè)黑帽seo工具
  • 漢口網(wǎng)站制作公司東莞有哪些做推廣的網(wǎng)站
  • 玩具網(wǎng)站模板紹興seo排名收費(fèi)
  • 沈陽網(wǎng)站建設(shè)團(tuán)隊(duì)杭州seo網(wǎng)絡(luò)推廣
  • 在本地做的網(wǎng)站怎么修改域名實(shí)體店?duì)I銷方案
  • 網(wǎng)站支付界面怎么做免費(fèi)推廣網(wǎng)站2024
  • 迪哥哪個網(wǎng)站上做游戲直播制作網(wǎng)頁完整步驟代碼
  • 網(wǎng)站做視頻窗口接口收費(fèi)么windows優(yōu)化大師的特點(diǎn)
  • 做服裝批發(fā)哪個網(wǎng)站比較好巨量引擎廣告投放平臺官網(wǎng)
  • 哪家公司建網(wǎng)站最好網(wǎng)站 推廣
  • 蘇州網(wǎng)頁制作與網(wǎng)站建設(shè)地址吸引顧客的營銷策略
  • 優(yōu)秀的定制網(wǎng)站建設(shè)公司河北seo網(wǎng)絡(luò)優(yōu)化師
  • 微信小程序開通要錢嗎seo超級外鏈發(fā)布
  • 室內(nèi)設(shè)計培訓(xùn)教程seo實(shí)戰(zhàn)培訓(xùn)中心