西宁网站建设开发,哪个网站有律师做的案件,公司网站运营方案,wordpress去除 版权信息目录 十一、手写Spring框架
第一步#xff1a;创建模块myspring
第二步#xff1a;准备好要管理的Bean
第三步#xff1a;准备myspring.xml配置文件
第四步#xff1a;核心接口实现
第五步#xff1a;实例化Bean
第六步#xff1a;给Bean属性赋值
第七步#xff…目录 十一、手写Spring框架
第一步创建模块myspring
第二步准备好要管理的Bean
第三步准备myspring.xml配置文件
第四步核心接口实现
第五步实例化Bean
第六步给Bean属性赋值
第七步测试
第八步打包发布
第十一步使用myspring框架 十一、手写Spring框架 Spring IoC容器的实现原理工厂模式解析XML反射机制。
第一步创建模块myspring 配置pom.xml文件 ?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersion
groupIdorg.myspringframework/groupIdartifactIdmyspring/artifactIdversion1.0.0/versionpackagingjar/packaging
dependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/versionscopetest/scope/dependency!--使用dom4j解析XML配置文件--dependencygroupIdorg.dom4j/groupIdartifactIddom4j/artifactIdversion2.1.3/version/dependencydependencygroupIdjaxen/groupIdartifactIdjaxen/artifactIdversion1.2.0/version/dependency/dependencies
propertiesmaven.compiler.source20/maven.compiler.sourcemaven.compiler.target20/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/properties
/project 第二步准备好要管理的Bean 这些Bean在将来开发完框架之后是要删除的。
User
package com.hhb.myspring.bean;
public class User {private String name;private int age;
public void setName(String name) {this.name name;}
public void setAge(int age) {this.age age;}
Overridepublic String toString() {return User{ name name \ , age age };}
}
UserDao
package com.hhb.myspring.bean;
public class UserDao {public void insert() {System.out.println(保存用户信息);}
}
UserService
package com.hhb.myspring.bean;
public class UserService {private UserDao userDao;
public void setUserDao(UserDao userDao) {this.userDao userDao;}
public void save() {userDao.insert();}
}
第三步准备myspring.xml配置文件 将来在框架开发完毕之后这个文件也是要删除的。 文件放在类的根路径下。
myspring.xml
?xml version1.0 encodingUTF-8?
beans
bean iduser classcom.hhb.myspring.bean.Userproperty namename value张三/property nameage value23//bean
bean iduserDaoBean classcom.hhb.myspring.bean.UserDao/
bean iduserService classcom.hhb.myspring.bean.UserServiceproperty nameuserDao refuserDaoBean//bean
/beans 使用value给简单属性赋值使用ref给非简单属性赋值。
第四步核心接口实现
ApplicationContext
package org.myspringframework.core;
/*** MySpring框架应用上下文接口。*/
public interface ApplicationContext {/*** 根据bean的名称获取对象的bean对象** param beanName myspring配置文件中bean标签的id* return 对应的单例bean对象*/Object getBean(String beanName);
}
ClassPathXmlApplicationContext
package org.myspringframework.core;
import java.util.HashMap;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
private MapString, Object singletonObjects new HashMap();
/*** 解析myspring的配置文件然后初始化所有的Bean对象** param configLocation spring配置文件的路径*/public ClassPathXmlApplicationContext(String configLocation) {//解析myspring.xml文件然后实例化Bean将Bean存放到singletonObjects集合当中
}
Overridepublic Object getBean(String beanName) {return singletonObjects.get(beanName);}
}
第五步实例化Bean
ClassPathXmlApplicationContext
package org.myspringframework.core;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
private static final Logger logger LoggerFactory.getLogger(ClassPathXmlApplicationContext.class);
private MapString, Object singletonObjects new HashMap();
/*** 解析myspring的配置文件然后初始化所有的Bean对象** param configLocation spring配置文件的路径*/public ClassPathXmlApplicationContext(String configLocation) {try {// 解析myspring.xml文件然后实例化Bean将Bean存放到singletonObjects集合当中。// 这是dom4j解析XML文件的核心对象。SAXReader reader new SAXReader();// 获取一个输入流指向配置文件InputStream in ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);// 读文件Document document reader.read(in);// 获取所有的bean标签ListNode nodes document.selectNodes(//bean);// 遍历bean标签nodes.forEach(node - {try {// 向下转型的目的是为了使用Element接口里更加丰富的方法。Element beanElt (Element) node;// 获取id属性String id beanElt.attributeValue(id);// 获取class属性String className beanElt.attributeValue(class);logger.info(beanName id);logger.info(beanClassName className);//通过反射机制创建对象将其放到Map集合中提前曝光//获取ClassClass? aClass Class.forName(className);//获取无参数构造方法Constructor? defaultCon aClass.getDeclaredConstructor();//调用无参数构造方法实例化BeanObject bean defaultCon.newInstance();//将Bean曝光加入到Map集合singletonObjects.put(id, bean);//记录日志logger.info(singletonObjects.toString());} catch (Exception e) {e.printStackTrace();}});} catch (DocumentException e) {e.printStackTrace();}}
Overridepublic Object getBean(String beanName) {return singletonObjects.get(beanName);}
}
第六步给Bean属性赋值
package org.myspringframework.core;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*** author 动力节点* version 1.0* className ClassPathXmlApplicationContext* since 1.0**/
public class ClassPathXmlApplicationContext implements ApplicationContext{
private static final Logger logger LoggerFactory.getLogger(ClassPathXmlApplicationContext.class);
private MapString, Object singletonObjects new HashMap();
/*** 解析myspring的配置文件然后初始化所有的Bean对象。* param configLocation spring配置文件的路径。注意使用ClassPathXmlApplicationContext配置文件应当放到类路径下。*/public ClassPathXmlApplicationContext(String configLocation) {try {// 解析myspring.xml文件然后实例化Bean将Bean存放到singletonObjects集合当中。// 这是dom4j解析XML文件的核心对象。SAXReader reader new SAXReader();// 获取一个输入流指向配置文件InputStream in ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);// 读文件Document document reader.read(in);// 获取所有的bean标签ListNode nodes document.selectNodes(//bean);// 遍历bean标签nodes.forEach(node - {try {// 向下转型的目的是为了使用Element接口里更加丰富的方法。Element beanElt (Element) node;// 获取id属性String id beanElt.attributeValue(id);// 获取class属性String className beanElt.attributeValue(class);logger.info(beanName id);logger.info(beanClassNameclassName);// 通过反射机制创建对象将其放到Map集合中提前曝光。// 获取ClassClass? aClass Class.forName(className);// 获取无参数构造方法Constructor? defaultCon aClass.getDeclaredConstructor();// 调用无参数构造方法实例化BeanObject bean defaultCon.newInstance();// 将Bean曝光加入Map集合singletonObjects.put(id, bean);// 记录日志logger.info(singletonObjects.toString());} catch (Exception e) {e.printStackTrace();}});
// 再次重新把所有的bean标签遍历一次这一次主要是给对象的属性赋值。nodes.forEach(node - {try {Element beanElt (Element) node;// 获取idString id beanElt.attributeValue(id);// 获取classNameString className beanElt.attributeValue(class);// 获取ClassClass? aClass Class.forName(className);// 获取该bean标签下所有的属性property标签ListElement propertys beanElt.elements(property);// 遍历所有的属性标签propertys.forEach(property - {try {// 获取属性名String propertyName property.attributeValue(name);// 获取属性类型Field field aClass.getDeclaredField(propertyName);logger.info(属性名 propertyName);// 获取set方法名String setMethodName set propertyName.toUpperCase().charAt(0) propertyName.substring(1);// 获取set方法Method setMethod aClass.getDeclaredMethod(setMethodName, field.getType());// 获取具体的值String value property.attributeValue(value); // 30Object actualValue null; // 真值String ref property.attributeValue(ref);if (value ! null) {// 说明这个值是简单类型// 调用set方法(set方法没有返回值)// 我们myspring框架声明一下我们只支持这些类型为简单类型// byte short int long float double boolean char// Byte Short Integer Long Float Double Boolean Character// String// 获取属性类型名String propertyTypeSimpleName field.getType().getSimpleName();switch (propertyTypeSimpleName) {case byte:actualValue Byte.parseByte(value);break;case short:actualValue Short.parseShort(value);break;case int:actualValue Integer.parseInt(value);break;case long:actualValue Long.parseLong(value);break;case float:actualValue Float.parseFloat(value);break;case double:actualValue Double.parseDouble(value);break;case boolean:actualValue Boolean.parseBoolean(value);break;case char:actualValue value.charAt(0);break;case Byte:actualValue Byte.valueOf(value);break;case Short:actualValue Short.valueOf(value);break;case Integer:actualValue Integer.valueOf(value);break;case Long:actualValue Long.valueOf(value);break;case Float:actualValue Float.valueOf(value);break;case Double:actualValue Double.valueOf(value);break;case Boolean:actualValue Boolean.valueOf(value);break;case Character:actualValue Character.valueOf(value.charAt(0));break;case String:actualValue value;}
setMethod.invoke(singletonObjects.get(id), actualValue);}if (ref ! null) {// 说明这个值是非简单类型// 调用set方法(set方法没有返回值)setMethod.invoke(singletonObjects.get(id), singletonObjects.get(ref));}} catch (Exception e) {e.printStackTrace();}});} catch (Exception e) {e.printStackTrace();}});} catch (Exception e) {e.printStackTrace();}}
Overridepublic Object getBean(String beanName) {return singletonObjects.get(beanName);}
}
第七步测试
Test
public void test1(){ApplicationContext applicationContextnew ClassPathXmlApplicationContext(myspring.xml);Object user applicationContext.getBean(user);System.out.println(user);
UserService userService (UserService) applicationContext.getBean(userService);userService.save();
} 第八步打包发布 第十一步使用myspring框架
配置pom.xml
dependencies!--用myspring框架需要引入依赖--dependencygroupIdorg.myspringframework/groupIdartifactIdmyspring/artifactIdversion1.0.0/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/versionscopetest/scope/dependency
/dependencies