# spring-study
**Repository Path**: linestyle007/spring-study
## Basic Information
- **Project Name**: spring-study
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-04-15
- **Last Updated**: 2021-11-02
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 准备工作
### reflections
扫描包工具类,可以指定某个包扫描下面的所有类。
1. pom.xml
```xml
org.reflections
reflections
0.9.11
```
2. 本次项目需要用到的案例
```java
// 根据注解获取类集合
Set> componentClasses reflections.getTypesAnnotatedWith(Component.class);
Set> serviceClasses reflections.getTypesAnnotatedWith(Service.class);
// 根据注解获取字段对象集合
Set fields = reflections.getFieldsAnnotatedWith(Autowire.class)
```
### guava
* CaseFormat:字符串格式转换工具类,可以在驼峰、下划线、横杆、大小写之间相互转换
```java
// "dao" -> "Dao"
String str = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, "dao");
```
## 实现步骤
* 创建容器
* 获取包扫描对象 reflections
* 创建bean工厂 beanFactory
* 注册bean事务处理器
* 实例化注解@Component,@Service的所有bean
* 获取bean
### 核心代码
```java
// 实现效果
public class AnnotationApplicationContextTest() {
@Test
public void test_getBean() {
AnnotationApplicationContext ctx = new AnnotationApplicationContext("org.example.*");
TransferService transferService = ctx.getBean(TransferServiceImpl.class);
// 实现转账失败,数据库数据回滚
transferService.transfer("6029621011000","6029621011001", 100);
}
}
// 容器类
public class AnnotationApplicationContext implements ApplicationContext {
public AnnotationApplicationContext(String packageScan) throws Exception {
// 1.获取包扫描对象 reflections
reflections = new Reflections(packageScan,
new TypeAnnotationsScanner(), new SubTypesScanner(), new FieldAnnotationsScanner());
// 2.创建bean工厂 beanFactory
beanFactory = new SimpleBeanFactory(reflections);
// 3.注册bean事务处理器
beanFactory.registerBeanPostProcessor(new TransactionBeanPostProcessor());
// 4.实例化注解@Component,@Service的所有bean
((SimpleBeanFactory)beanFactory).preInstanceBeans();
}
}
```
### 创建容器
#### 获取包扫描对象 reflections
```java
/**
* packageScan: 扫描包路径,如org.example.*
* TypeAnnotationsScanner: 类扫描器
* Set> componentClasses reflections.getTypesAnnotatedWith(Component.class);
* Set> serviceClasses reflections.getTypesAnnotatedWith(Service.class);
* SubTypesScanner:子类扫描器
* Class implClass = reflections.getSubTypesOf(TransferService.class).stream().findFirst().get();
* FieldAnnotationsScanner:注解字段扫描
* Set autowireFields = reflections.getFieldsAnnotatedWith(Autowire.class);
*/
Reflections reflections = new Reflections(packageScan,
new TypeAnnotationsScanner(), new SubTypesScanner(), new FieldAnnotationsScanner());
```
#### 创建bean工厂 beanFactory
```java
// 将创建bean工作委托给beanFactory
beanFactory = new SimpleBeanFactory(Reflections reflections) {
this.reflections = reflections;
// 实例化所有bean
preInstanceBeans() {
// 获取需要实例化的bean
Set> preInstanceBeanClasses = matcherPreInstanceBeanClasses() {
return ImmutableSet.>builder()
.addAll(reflections.getTypesAnnotatedWith(Component.class))
.addAll(reflections.getTypesAnnotatedWith(Service.class))
.build();
}
// 实例化
for (Class> beanClass : preInstanceBeanClasses) {
doGetBean(beanClass);
}
}
};
```
#### doGetBean
* 实例化bean
* 设置属性
* aop增强
* 加入缓存
* 返回
```java
Object doGetBean(Class> clazz)
{
Object obj;
String beanName;
// ************ buildingBeanNames.get().contains(beanName) 检查循环依赖,throw异常
// 1.实例化bean
obj = clazz.newInstance();
// ************ buildingBeanNames.get().add(beanName)
beanName = BeanUtils.getBeanName(obj.getClass().getSimpleName());
log.info("{} instance...", obj.getClass().getSimpleName());
// 2.设置属性
setPropertyDIValues(obj) {
// 获取注入字段列表 {fieldName: Field对象}
Map autowireFieldMap = ReflectionUtils.getAllFields(clazz, field -> field.getAnnotation(Autowire.class) != null)
.stream().collect(Collectors.toMap(Field::getName, Function.identity()));
// 执行setter方法设值
Set setterMethods = ReflectionUtils.getMethods(clazz, method -> autowireFieldMap.containsKey(getBeanNameOfSetter(method)));
for (Method setterMethod : setterMethods) {
ref = cacheBeanMap.get(beanName));
if (ref == null) {
// 如何为空,调用doGetBean创建一个
// 循环依赖问题? 后续优化 -> 引入一个ThreandLocal> buildingBeanNames,不允许依赖即可
ref = this.doGetBean(getRefClass(autowireFieldMap.get(beanName)));
}
// invoke setter
setterMethod.invoke(obj, ref);
}
}
// ************ buildingBeanNames.get().remove(beanName)
// 3.aop增强
obj = before(obj);
doInit(obj);
obj = after(obj);
// 4.加入缓存
cacheBeanMap.put(beanName, obj);
// 5.返回
return obj;
}
```
#### 事务处理器
TransactionBeanPostProcessor
```java
// 是在初始化容器时注入的
public AnnotationApplicationContext(String packageScan) throws Exception {
reflections = new Reflections(packageScan,
new TypeAnnotationsScanner(), new SubTypesScanner(), new FieldAnnotationsScanner());
beanFactory = new SimpleBeanFactory(reflections);
// 注册事务处理器 // 这里>>>>>
beanFactory.registerBeanPostProcessor(new TransactionBeanPostProcessor());
// 预实例化
((SimpleBeanFactory)beanFactory).preInstanceBeans();
}
// 什么时候调用的?在哪调用的? -> 预实例化方法
preInstanceBeans() {
// 获取需要实例化的bean
Set> preInstanceBeanClasses = matcherPreInstanceBeanClasses();
// 实例化
for (Class> beanClass : preInstanceBeanClasses) {
doGetBean(beanClass) {
// 1.实例化bean
...
// 2.设置属性
// 3.aop增强
obj = before(obj);
doInit(obj);
obj = after(obj) { // 这里调用的 >>>>>
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
obj = beanPostProcessor.after(obj);
}
return obj;
}
// 4.加入缓存
// 5.返回
return obj;
}
}
}
TransactionBeanPostProcessor implements BeanPostProcessor {
@Override
public Object after(Object obj) {
/***
* 对这样的类开始事务
* @Trancation
* class xxService { ... }
*/
boolean enableTransaction = (obj.getClass().getAnnotation(Transaction.class) != null);
if (enableTransaction) {
obj = AopProxyUtils.getProxy(obj)
{ // 创建代理
$proxy.invoke(Object proxy, Method method, Object[] args) -> {
// 判断方法是否开启事务
Transaction transaction;
boolean methodEnabled = (transaction = method.getAnnotation(Transaction.class)) != null
&& transaction.methodEnabled();
if (!methodEnabled) {
log.info("{}.{}->不开启事务...", method.getDeclaringClass().getName(), method.getName());
return method.invoke(obj, args);
}
// 需要开启事务
Object result = null;
// 开启事务
try{
// 开启事务(关闭事务的自动提交)
log.info("{}.{}->开启事务...", method.getDeclaringClass().getName(), method.getName());
TransactionManager.beginTransaction();
result = method.invoke(obj,args);
// 提交事务
log.info("{}.{}->提交事务...", method.getDeclaringClass().getName(), method.getName());
TransactionManager.commit();
}catch (Exception e) {
// 回滚事务
log.info("{}.{}->回滚事务...", method.getDeclaringClass().getName(), method.getName());
TransactionManager.rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
return result;
}
}
}
return obj;
}
}
```
### 获取bean
```java
public interface BeanFactory {
T getBean(Class> clazz);
T getBean(String className);
/**
* 注册处理器
* @param beanPostProcessor
*/
void registerBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
public class SimpleBeanFactory implements BeanFactory {
/** bean缓存Map */
Map cacheBeanMap = Maps.newConcurrentMap();
...
@Override
public T getBean(Class> clazz) {
return this.getBean(clazz.getSimpleName());
}
@Override
public T getBean(String className) {
return (T) cacheBeanMap.get(BeanUtils.getBeanName(className));
}
}
```