资讯类网站如何填充内容(Spring手撸专栏:编程开发来讲,丢三落四、乱码七糟)
优采云 发布时间: 2021-12-26 23:15资讯类网站如何填充内容(Spring手撸专栏:编程开发来讲,丢三落四、乱码七糟)
博客:
沉淀、分享、成长,让你和他人有所收获!
《春季手册专栏》目录一、前言
超卖,掉单,幂等,你的程序总是不耐打!
想了想,运营宣传活动已经七八天了,最后一天开心的等着页面上线。突然一堆异常,资金损失,闪退,用户流量转瞬即逝,我终于想死了。有你的心!
就编程开发而言,四、乱码丢了。也许这就是大多数初级程序员日常发展的真实写照。即使有测试人员的验证,也会有错误上线。,只是当时没找到而已!因为人写代码,都会有错误,即使是老码农
在程序Bug方面,将包括产品PRD过程中的Bug,操作配置活动中的Bug,研发和开发中功能实现中的Bug,测试验证过程中缺失的Bug,以及运维配置中的Bug。在线过程中的维护服务。其实,这些都可以通过工艺规范的制定和一定的研发经验的积累,逐渐减少。
另一种是沟通留下的bug。通常,提出业务需求,确定产品计划,并实施研发。最终,UI、测试、运维、架构等人员参与了一个项目的承接。从开发到线上运营,其实很难在这群人之间维持统一的信息传播。比如在项目开发的中途,运营对产品提出了新的需求,产品觉得功能不大,然后找到了相应的前端开发和逻辑,没想到它也可能影响后端开发和测试用例。最终功能虽然上线了,但并不在生产、研究、测试的全部需求覆盖范围内,
所以,如果你想让你的程序非常耐打,抓住农民的三拳,那么你要做的不仅仅是一个简单的搬砖农民!
二、目标
首先我们回顾一下这几章的内容,包括:实现一个容器,定义和注册Beans,实例化Beans,根据是否收录
构造函数来实现不同的实例化策略。那么在创建对象实例化时缺少什么?其实这个类中是否有属性还缺少一个问题。如果类中有属性,那么实例化时需要填写属性信息,这样才能创建一个完整的对象。
属性的填充不仅是int、Long、String,还有尚未实例化的对象属性,都需要在创建Bean的时候进行填充。但是这里我们暂时不考虑Bean的循环依赖,否则整个功能都会被扩展,让新人在学习的时候掌握不了。核心功能陆续实现后,会逐步完善。
三、设计
由于使用newInstance或Cglib创建Bean后,属性填充开始完成属性信息,那么可以在AbstractAutowireCapableBeanFactory类的createBean方法中添加完整的属性方法。在这部分实习中,还可以学习Spring源码。这里的实现也是简化版的Spring,后续对比研究会更容易理解
四、实现1. 项目结构
small-spring-step-04
└── src ├── main │ └── java │ └── cn.bugstack.springframework.beans │ ├── factory │ │ ├── factory │ │ │ ├── BeanDefinition.java │ │ │ ├── BeanReference.java │ │ │ └── SingletonBeanRegistry.java │ │ ├── support │ │ │ ├── AbstractAutowireCapableBeanFactory.java │ │ │ ├── AbstractBeanFactory.java │ │ │ ├── BeanDefinitionRegistry.java │ │ │ ├── CglibSubclassingInstantiationStrategy.java │ │ │ ├── DefaultListableBeanFactory.java │ │ │ ├── DefaultSingletonBeanRegistry.java │ │ │ ├── InstantiationStrategy.java │ │ │ └── SimpleInstantiationStrategy.java │ │ └── BeanFactory.java │ ├── BeansException.java │ ├── PropertyValue.java │ └── PropertyValues.java └── test └── java └── cn.bugstack.springframework.test ├── bean │ ├── UserDao.java │ └── UserService.java └── ApiTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
项目源码:公众号“bugstack虫洞栈”,回复:Spring专栏,获取完整源码
Spring Bean容器类关系,如图5-2
2. 定义属性
cn.bugstack.springframework.beans.PropertyValue
public class PropertyValue { private final String name; private final Object value; public PropertyValue(String name, Object value) { this.name = name; this.value = value; } // ...get/set
}
1
2
3
4
5
6
7
8
9
10
11
12
13
cn.bugstack.springframework.beans.PropertyValues
public class PropertyValues { private final List propertyValueList = new ArrayList(); public void addPropertyValue(PropertyValue pv) { this.propertyValueList.add(pv); } public PropertyValue[] getPropertyValues() { return this.propertyValueList.toArray(new PropertyValue[0]); } public PropertyValue getPropertyValue(String propertyName) { for (PropertyValue pv : this.propertyValueList) { if (pv.getName().equals(propertyName)) { return pv; } } return null; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3. Bean 定义完成
cn.bugstack.springframework.beans.factory.config.BeanDefinition
public class BeanDefinition { private Class beanClass; private PropertyValues propertyValues; public BeanDefinition(Class beanClass) { this.beanClass = beanClass; this.propertyValues = new PropertyValues(); } public BeanDefinition(Class beanClass, PropertyValues propertyValues) { this.beanClass = beanClass; this.propertyValues = propertyValues != null ? propertyValues : new PropertyValues(); } // ...get/set
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
4. Bean 属性填充
cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class beanClass = beanDefinition.getBeanClass(); Constructor[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
五、测试1.提前准备
cn.bugstack.springframework.test.bean.UserDao
public class UserDao { private static Map hashMap = new HashMap(); static { hashMap.put("10001", "小傅哥"); hashMap.put("10002", "八杯水"); hashMap.put("10003", "阿毛"); } public String queryUserName(String uId) { return hashMap.get(uId); }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cn.bugstack.springframework.test.bean.UserService
public class UserService { private String uId; private UserDao userDao; public void queryUserInfo() { System.out.println("查询用户信息:" + userDao.queryUserName(uId)); } // ...get/set
}
1
2
3
4
5
6
7
8
9
10
11
12
2. 测试用例
@Test
public void test_BeanFactory() { // 1.初始化 BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2. UserDao 注册 beanFactory.registerBeanDefinition("userDao", new BeanDefinition(UserDao.class)); // 3. UserService 设置属性[uId、userDao] PropertyValues propertyValues = new PropertyValues(); propertyValues.addPropertyValue(new PropertyValue("uId", "10001")); propertyValues.addPropertyValue(new PropertyValue("userDao",new BeanReference("userDao"))); // 4. UserService 注入bean BeanDefinition beanDefinition = new BeanDefinition(UserService.class, propertyValues); beanFactory.registerBeanDefinition("userService", beanDefinition); // 5. UserService 获取bean UserService userService = (UserService) beanFactory.getBean("userService"); userService.queryUserInfo();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
3. 测试结果
查询用户信息:小傅哥
Process finished with exit code 0
1
2
3
六、总结七、系列推荐