概述
bean.xml
<beans>
<bean id="studentService" class="com.hgd.spring.service.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
<bean id="userService" class="com.hgd.spring.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.hgd.spring.dao.UserDaoImpl"></bean>
<bean id="studentDao" class="com.hgd.spring.dao.StudentDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test3?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
</beans>
封装beans标签数据类(BeanDefinition)
public class BeanDefinition {
private String className;//class
private String beanName; //id
private String initMethod; //init_method
//该配置是默认配置,单例
private String scope;
private static final String SCOPE_SINGLETON = "singleton";
private static final String SCOPE_PROTOTYPE = "prototype";
/**
* bean中的属性信息
*/
private List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public BeanDefinition(String className, String beanName) {
this.className = className;
this.beanName = beanName;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getInitMethod() {
return initMethod;
}
public void setInitMethod(String initMethod) {
this.initMethod = initMethod;
}
public List<PropertyValue> getPropertyValues() {
return propertyValues;
}
public void addPropertyValue(PropertyValue propertyValue) {
this.propertyValues.add(propertyValue);
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public void setPropertyValues(List<PropertyValue> propertyValues) {
this.propertyValues = propertyValues;
}
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope);
}
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
@Override
public String toString() {
return "BeanDefinition{" +
"className='" + className + ''' +
", beanName='" + beanName + ''' +
", initMethod='" + initMethod + ''' +
", scope='" + scope + ''' +
", propertyValues=" + propertyValues +
'}';
}
}
封装properties的数据信息(PropertyValue)
public class PropertyValue {
private String name;
private Object value;
public PropertyValue(String name, Object value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
@Override
public String toString() {
return "PropertyValue{" +
"name='" + name + ''' +
", value=" + value +
'}';
}
}
封装ref的数据类(RuntimeBeanReference)
public class RuntimeBeanReference {
private String ref;
public RuntimeBeanReference(String ref) {
this.ref = ref;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}
封装value的数据类(TypedStringValue)
public class TypedStringValue {
private String value;
private Class<?> targetType;
public TypedStringValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Class<?> getTargetType() {
return targetType;
}
public void setTargetType(Class<?> targetType) {
this.targetType = targetType;
}
}
解析ioc和封装ioc思路
public class IocDemo {
//单例bean存放map集合
private static Map<String,Object> singletonObjects=new HashMap<String, Object>();
//封装xml中的bean标签表示的信息
private Map<String, BeanDefinition> beanDefinitionMap=new HashMap<String, BeanDefinition>();
@Before
public void demo(){
loadAndRegisterBeanDefinitions("beans.xml");
Set<Map.Entry<String, BeanDefinition>> entries = beanDefinitionMap.entrySet();
for (Map.Entry<String, BeanDefinition> entry : entries) {
System.out.println(entry.getKey()+"="+entry.getValue());
}
}
@Test
public void iocTest(){
// StudentService studentService = (StudentService)getBean("studentService");
// List<Student> all = studentService.findAll();
// for (Student student : all) {
// System.out.println("student = " + student);
// }
UserService userService=(UserService)getBean("userService");
userService.say();
//UserDao userDao=(UserDao)getBean("userDao");
//userDao.say();
// BasicDataSource basicDataSource=(BasicDataSource)getBean("dataSource");
// System.out.println(basicDataSource.getDriverClassName());
// System.out.println(basicDataSource.getUrl());
// System.out.println(basicDataSource.getUsername());
// System.out.println(basicDataSource.getPassword());
}
private Object getBean(String beanName) {
System.out.println("beanName = " + beanName);
Object singletonObject= singletonObjects.get(beanName);
if (singletonObject != null) {
return singletonObject;
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) {
return null;
}
List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
System.out.println("propertyValues = " + propertyValues);
//判断是否是单例还是多例
if (beanDefinition.isSingleton()){
//单例
singletonObject=createBean(beanDefinition);
this.singletonObjects.put(beanName, singletonObject);
}else if (beanDefinition.isPrototype()){
//多例
singletonObject=createBean(beanDefinition);
}
return singletonObject;
}
private Object createBean(BeanDefinition beanDefinition) {
String className = beanDefinition.getClassName();
Class<?> clazz = resolveClass(className);
if (clazz == null) {
return null;
}
//实例化 new
Object bean=createBeanInstance(clazz);
// 属性填充 set
populateBean(bean, beanDefinition);
// 初始化 init
initBean(bean, beanDefinition);
return bean;
}
//实例化
private Object createBeanInstance(Class<?> clazz) {
// TODO 可以根据bean标签的配置选择使用实例工厂去创建Bean
// TODO 可以根据bean标签的配置选择使用静态工厂去创建Bean
// 还可以选择使用我们的构造方法去创建Bean
return createObject(clazz);
}
private Object createObject(Class<?> clazz, Object... args) {
try {
System.out.println("args = " + args);
// TODO 可以根据输入参数获取指定构造参数的构造方法
Constructor<?> constructor = clazz.getDeclaredConstructor();
// 默认调用无参构造进行对象的创建
return constructor.newInstance(args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//实例化
// private Object createInstance(BeanDefinition beanDefinition) {
// try {
// String clazzName = beanDefinition.getClassName();
// Class<?> clazzType = resolveClass(clazzName);
// Constructor<?> constructor = clazzType.getConstructor();
// Object bean = constructor.newInstance();
// return bean;
// } catch (Exception e) {
// e.printStackTrace();
// }
// return null;
// }
private Class<?> resolveClass(String className) {
try {
Class<?> clazz = Class.forName(className);
return clazz;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
//属性填充
private void populateBean(Object bean, BeanDefinition beanDefinition) {
List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
Object valueToUse = null;
if (value instanceof TypedStringValue) {
TypedStringValue typedStringValue = (TypedStringValue) value;
String stringValue = typedStringValue.getValue();
Class<?> targetType = typedStringValue.getTargetType();
if (targetType == String.class) {
valueToUse = stringValue;
} else if (targetType == Integer.class) {
valueToUse = Integer.parseInt(stringValue);
} // ....
} else if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference reference = (RuntimeBeanReference) value;
String ref = reference.getRef();
// 创建一个bean的时候,根据依赖注入情况,自动去创建另一个bean去注入
valueToUse = getBean(ref);
}
setProperty(bean, name, valueToUse);
}
}
private void setProperty(Object bean, String name, Object valueToUse) {
try {
Class<?> clazz = bean.getClass();
System.out.println("clazz = " + clazz);
//返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
//name 参数是一个 String,它指定所需字段的简称
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(bean, valueToUse);
} catch (Exception e) {
e.printStackTrace();
}
}
//初始化
private void initBean(Object bean, BeanDefinition beanDefinition) {
// TODO Aware接口会在此时被处理
invokeInitMethod(bean, beanDefinition);
}
private void invokeInitMethod(Object bean, BeanDefinition beanDefinition) {
// bean标签配置了init-method属性
String initMethod = beanDefinition.getInitMethod();
if (initMethod == null || initMethod.equals("")) {
return;
}
invokeMethod(bean, initMethod);
// TODO bean标签实现了InitializingBean接口
}
private void invokeMethod(Object bean, String initMethod) {
try {
Class<?> clazz = bean.getClass();
Method method = clazz.getDeclaredMethod(initMethod);
method.invoke(bean);
} catch (Exception e) {
e.printStackTrace();
}
}
private void loadAndRegisterBeanDefinitions(String location) {
//加载流对象
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(location);
//通过sax解析
Document document = DocumentUtils.createDocument(resourceAsStream);
//解析beans文件
parseXMLBeans(document.getRootElement());
}
//解析beans文件
private void parseXMLBeans(Element rootElement) {
List<Element> elements = rootElement.elements();
for (Element beanElement : elements) {
//获取标签的名称
String name = beanElement.getName();
if (name.equals("bean")){
//解析<bean>
parseXMLBean(beanElement);
}else {
//解析自定义标签
parseXMLCustom(beanElement);
}
}
}
//解析自定义标签
private void parseXMLCustom(Element beanElement) {
}
//解析<bean>
private void parseXMLBean(Element beanElement) {
if (beanElement == null) {
return;
}
String id = beanElement.attributeValue("id");
String clazz = beanElement.attributeValue("class");
String initMethod = beanElement.attributeValue("init-method");
String scope = beanElement.attributeValue("scope");
if (scope==null) scope="singleton";
//将数据封装到
BeanDefinition beanDefinition=new BeanDefinition(clazz, id);
beanDefinition.setInitMethod(initMethod);
beanDefinition.setScope(scope);
//解析bean的子标签
List<Element> propertyElements = beanElement.elements();
for (Element propertyElement : propertyElements) {
parseXMLProperties(beanDefinition,propertyElement);
}
//注册beanDefinition信息
this.beanDefinitionMap.put(id, beanDefinition);
}
//解析properties文件
private void parseXMLProperties(BeanDefinition beanDefinition, Element propertyElement) {
if (propertyElement == null) {
return;
}
//获取name属性
String name = propertyElement.attributeValue("name");
String value = propertyElement.attributeValue("value");
String ref = propertyElement.attributeValue("ref");
// 如果value和ref都有值,则返回
if (value != null && !value.equals("") && ref != null && !ref.equals("")) {
return;
}
PropertyValue propertyValue=null;
if (value!=null && !value.equals("")){
// 因为spring配置文件中的value是String类型,而对象中的属性值是各种各样的,所以需要存储类型
TypedStringValue typeStringValue = new TypedStringValue(value);
Class<?> targetType = getTypeByFieldName(beanDefinition.getClassName(),name);
typeStringValue.setTargetType(targetType);
propertyValue = new PropertyValue(name, typeStringValue);
beanDefinition.addPropertyValue(propertyValue);
}else if (ref!=null && !ref.equals("")){
RuntimeBeanReference reference=new RuntimeBeanReference(ref);
propertyValue=new PropertyValue(name, reference);
beanDefinition.addPropertyValue(propertyValue);
}else {
return;
}
}
private Class<?> getTypeByFieldName(String beanClassName, String name) {
try {
Class<?> clazz = Class.forName(beanClassName);
Field field = clazz.getDeclaredField(name);
return field.getType();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
最后
以上就是糊涂柠檬为你收集整理的手写ioc代码的全部内容,希望文章能够帮你解决手写ioc代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复