package com.kkb.spring.test;
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.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import com.kkb.spring.ioc.BeanDefinition;
import com.kkb.spring.ioc.PropertyValue;
import com.kkb.spring.ioc.RuntimeBeanReference;
import com.kkb.spring.ioc.TypedStringValue;
import com.kkb.spring.po.User;
import com.kkb.spring.service.UserService;
public class TestSpringV2222 {
private Map<String, BeanDefinition> beanDefinitions = new HashMap<>();
/**
* 专门存储单例bean实例的集合
*/
private Map<String, Object> singletonObjects = new HashMap<String, Object>();
@Test
public void test() throws Exception {
// 读取XML中的配置信息,封装成BeanDefinition,并且注册到Map集合中
loadAndregisterBeanDefinitions("beans.xml");
// 获取UserService的bean实例
UserService userService = (UserService) getBean("userService");
// 调用UserService的方法
// 入参对象
Map<String, Object> param = new HashMap<>();
param.put("username", "王五");
// 根据用户名称查询用户信息
List<User> users = userService.queryUsers(param);
System.out.println("结果:" + users);
}
private Object getBean(String name) {
// 从缓存中获取要找的对象
Object singleton = this.singletonObjects.get(name);
if (singleton != null) {
return singleton;
}
// 找不到,则获取指定名称的BeanDefinition对象
// 此处使用到的就是抽象模板方法,我此处只定流程,不去实现,我也不懂如何实现,这不是我干的事情
BeanDefinition bd = this.beanDefinitions.get(name);
// 根据BeanDefinition中的信息,判断是单例还是多例(原型)
if (bd.isSingleton()) { // 单例
// 根据BeanDefinition对象,完成bean的创建
singleton = createBean(bd);
// 缓存已经创建的单例bean实例
this.singletonObjects.put(name, singleton);
} else if (bd.isPrototype()) {// 原型
// 根据BeanDefinition对象,完成bean的创建
singleton = createBean(bd);
}
return singleton;
}
private Object createBean(BeanDefinition bd) {
Class<?> clazz = bd.getClazzType();
if (clazz == null) {
return null;
}
// 实例化bean
// 注意:此时只是new了一个空对象
Object sinleton = createBeanInstance(clazz);
// bean的属性填充
populateBean(sinleton, bd);
// 初始化bean
initBean(sinleton, bd);
return sinleton;
}
private void initBean(Object sinleton, BeanDefinition bd) {
// TODO 完成Aware接口(标记接口)相关的处理,spring mvc代码会用到
// 1. aware接口的处理
// TODO BeanPostProcessor的前置方法执行
initMethod(sinleton, bd);
// TODO BeanPostProcessor的后置方法执行(AOP代理对象产生的入口)
}
private void initMethod(Object sinleton, BeanDefinition bd) {
// TODO 完成InitializingBean接口(标记接口)的处理,调用的是afterPropertySet方法
// 完成init-metho标签属性对应的方法调用
invokeMethod(sinleton, bd.getInitMethod());
}
private void setProperty(Object beanInstance, String name, Object valueToUse) {
try {
Class<?> clazz = beanInstance.getClass();
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(beanInstance, valueToUse);
} catch (Exception e) {
e.printStackTrace();
}
}
private void invokeMethod(Object beanInstance, String initMethod) {
try {
if (initMethod == null || "".equals(initMethod)) {
return;
}
Class<?> clazz = beanInstance.getClass();
Method method = clazz.getDeclaredMethod(initMethod);
// 设置允许访问私有方法和变量,此处也称之为暴力破解
method.setAccessible(true);
method.invoke(beanInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
private void populateBean(Object sinleton, BeanDefinition bd) {
List<PropertyValue> propertyValues = bd.getPropertyValues();
for (PropertyValue propertyValue : propertyValues) {
// 获取属性名称
String name = propertyValue.getName();
// 未处理的value对象
Object value = propertyValue.getValue();
// 解决之后的value值
Object valueToUse = null;
if (value instanceof TypedStringValue) {
TypedStringValue typedStringValue = (TypedStringValue) value;
String stringValue = typedStringValue.getValue();
// 获取参数的类型
Class<?> targetType = typedStringValue.getTargetType();
// TODO 建议使用策略模式进行优化
if (targetType == Integer.class) {
valueToUse = Integer.parseInt(stringValue);
} else if (targetType == String.class) {
valueToUse = stringValue;
} else {
// ....
}
} else if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference reference = (RuntimeBeanReference) value;
// 递归获取指定名称的bean实例
// TODO 此处可能会发送循环依赖问题
valueToUse = getBean(reference.getRef());
} else {
// ....
}
// 利用反射去设置bean的属性
setProperty(sinleton, name, valueToUse);
}
}
private Object createBeanInstance(Class<?> clazz) {
// TODO 可以根据bean标签的配置选择使用实例工厂去创建Bean
// TODO 可以根据bean标签的配置选择使用静态工厂去创建Bean
// 还可以选择使用我们的构造方法去创建Bean
return createObject(clazz);
}
private Object createObject(Class<?> clazz, Object... args) {
try {
// TODO 可以根据输入参数获取指定构造参数的构造方法
Constructor<?> constructor = clazz.getConstructor();
// 默认调用无参构造进行对象的创建
return constructor.newInstance(args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void loadAndregisterBeanDefinitions(String location) {
// 获取流对象
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(location);
// 创建文档对象
Document document = createDocument(inputStream);
// 按照spring定义的标签语义去解析Document文档
registerBeanDefinitions(document.getRootElement());
}
private Document createDocument(InputStream inputStream) {
Document document = null;
try {
SAXReader reader = new SAXReader();
document = reader.read(inputStream);
return document;
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
@SuppressWarnings("unchecked")
public void registerBeanDefinitions(Element rootElement) {
// 获取<bean>和自定义标签(比如mvc:interceptors)
List<Element> elements = rootElement.elements();
for (Element element : elements) {
// 获取标签名称
String name = element.getName();
if (name.equals("bean")) {
// 解析默认标签,其实也就是bean标签
parseDefaultElement(element);
} else {
// 解析自定义标签,比如mvc:interceptors标签回去
parseCustomElement(element);
}
}
}
@SuppressWarnings("unchecked")
private void parseDefaultElement(Element beanElement) {
try {
if (beanElement == null)
return;
// 获取id属性
String id = beanElement.attributeValue("id");
// 获取name属性
String name = beanElement.attributeValue("name");
// 获取class属性
String clazzName = beanElement.attributeValue("class");
if (clazzName == null || "".equals(clazzName)) {
return;
}
Class<?> clazzType = Class.forName(clazzName);
// 获取init-method属性
String initMethod = beanElement.attribu
没有合适的资源?快使用搜索试试~ 我知道了~
spring ioc模块手写demo
共95个文件
java:35个
class:34个
xml:10个
需积分: 1 0 下载量 128 浏览量
2023-04-22
23:10:09
上传
评论
收藏 27KB 7Z 举报
温馨提示
spring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写
资源推荐
资源详情
资源评论
收起资源包目录
vip-class(5).7z (95个子文件)
spring-custom
.classpath 1KB
.settings
org.eclipse.jdt.core.prefs 243B
org.eclipse.core.resources.prefs 93B
org.eclipse.m2e.core.prefs 90B
pom.xml 2KB
src
test
resources
java
main
resources
beans3.xml 799B
sqlmapping.properties 94B
beans2.xml 1KB
beans.xml 809B
java
com
kkb
spring
utils
SimpleTypeRegistry.java 2KB
dao
UserDaoImpl.java 3KB
UserDao.java 202B
service
UserService.java 205B
UserServiceImpl.java 463B
aop
test
TestSpringV1.java 1KB
TestSpringV2222.java 11KB
TestSpringV2.java 11KB
TestSpringV3333.java 1KB
TestSpringV3.java 1KB
po
User.java 1017B
ioc
TypedStringValue.java 665B
PropertyValue.java 533B
BeanDefinition.java 2KB
RuntimeBeanReference.java 408B
advice
MyAdvice.java 1KB
target
classes
beans3.xml 799B
sqlmapping.properties 94B
beans2.xml 1KB
beans.xml 809B
META-INF
MANIFEST.MF 129B
maven
com.kkb
spring-custom
pom.properties 239B
pom.xml 2KB
com
kkb
spring
utils
SimpleTypeRegistry.class 1KB
dao
UserDao.class 332B
UserDaoImpl.class 4KB
service
UserService.class 341B
UserServiceImpl.class 1010B
aop
test
TestSpringV2.class 10KB
TestSpringV1.class 2KB
TestSpringV2222.class 11KB
TestSpringV3.class 2KB
po
User.class 2KB
ioc
TypedStringValue.class 1KB
PropertyValue.class 945B
BeanDefinition.class 3KB
RuntimeBeanReference.class 634B
advice
MyAdvice.class 1KB
test-classes
.project 565B
spring-framework-custom-13
.classpath 1KB
.settings
org.eclipse.jdt.core.prefs 243B
org.eclipse.core.resources.prefs 93B
org.eclipse.m2e.core.prefs 90B
pom.xml 1KB
src
test
resources
java
main
resources
java
com
kkb
spring
resource
ClasspathResource.java 466B
Resource.java 212B
utils
DocumentReader.java 574B
ReflectUtils.java 2KB
factory
BeanFactory.java 178B
ListableBeanFactory.java 191B
support
DefaultListableBeanFactory.java 937B
AbstractBeanFactory.java 2KB
AbstractAutowireCapableBeanFactory.java 3KB
AutowireCapableBeanFactory.java 185B
registry
SingletonBeanRegistry.java 176B
support
DefaultSingletonBeanRegistry.java 592B
BeanDefinitionRegistry.java 453B
ioc
TypedStringValue.java 665B
PropertyValue.java 533B
BeanDefinition.java 2KB
RuntimeBeanReference.java 408B
reader
XmlBeanDefinitionReader.java 863B
XmlBeanDefinitionDocumentReader.java 4KB
target
classes
META-INF
MANIFEST.MF 129B
maven
com.kkb
spring-framework-custom-13
pom.properties 278B
pom.xml 1KB
com
kkb
spring
resource
Resource.class 169B
ClasspathResource.class 824B
utils
DocumentReader.class 889B
ReflectUtils.class 3KB
factory
AutowireCapableBeanFactory.class 198B
BeanFactory.class 226B
support
AbstractAutowireCapableBeanFactory.class 3KB
DefaultListableBeanFactory.class 1KB
AbstractBeanFactory.class 1KB
ListableBeanFactory.class 184B
registry
SingletonBeanRegistry.class 339B
support
DefaultSingletonBeanRegistry.class 1KB
BeanDefinitionRegistry.class 528B
ioc
TypedStringValue.class 1KB
PropertyValue.class 945B
BeanDefinition.class 3KB
RuntimeBeanReference.class 634B
reader
XmlBeanDefinitionDocumentReader.class 4KB
XmlBeanDefinitionReader.class 1KB
test-classes
.project 578B
共 95 条
- 1
资源评论
Java码库
- 粉丝: 1455
- 资源: 3918
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab实现多车辆车辆路径问题,用遗传算法编程,保证可用.rar
- 基于matlab实现多层极限学习机实现手写体识别,准确率超过99%.rar
- 基于matlab实现电力系统最优潮流程序,可以应用于电力市场下的最优潮流计算 适合电力系统专业的同仁使用.rar
- 串行通信的通信协议串口协议串行通信的通信协议串口协议
- Vue构建交互式的单页面应用程序Vue构建交互式的单页面应用程序
- Spring Boot快速搭建和部署应用程序
- Redis开源的高性键值存储系统广泛应用于缓存、实时消息传递
- Qt跨平台的应用程序开发框架Qt跨平台的应用程序开发框架
- 单片机是集成处理器、存储器和输入输出设备
- 深度学习机器习方法模仿人脑神经网络深度学习机器习方法模仿人脑神经网络
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功