# OZAnnoIocDemo
**Repository Path**: orangezh/OZAnnoIocDemo
## Basic Information
- **Project Name**: OZAnnoIocDemo
- **Description**: 实现简单的Spring的Ioc容器,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解
- **Primary Language**: Java
- **License**: MulanPSL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 2
- **Created**: 2020-09-12
- **Last Updated**: 2022-07-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# OZAnnoIocDemo
#### 介绍
实现简单的Spring的Ioc容器,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解
#### 什么是IOC
IoC Inversion of Control (控制反转/反转控制),它是⼀个技术思想,不是⼀个技术实现
描述的事情:Java开发领域对象的创建,管理的问题
传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象
IoC思想下开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可
我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列事情)
为什么叫做控制反转?
控制:指的是对象创建(实例化、管理)的权利
反转:控制权交给外部环境了(spring框架、IoC容器)
IoC解决对象之间的耦合问题
IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样
IOC容器示例
#### 什么是AOP
AOP: Aspect oriented Programming ⾯向切⾯编程/⾯向⽅⾯编程
AOP是OOP的延续,从OOP说起
OOP三⼤特征:封装、继承和多态
OOP是⼀种垂直继承体系,而AOP是一种纵向的体系
比如:想在多个业务方法运行前后记录日志,为了不影响业务代码那么就抽象出一个横切逻辑单读维护
#### 手写实现IOC和AOP
案例实现了IOC容器的管理,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解,其中@Transactional就属于AOP的一种实现(动态代理)
- 导入必要的依赖包
```
junit
junit
4.12
mysql
mysql-connector-java
8.0.21
com.alibaba
druid
1.1.21
javax.servlet
javax.servlet-api
3.1.0
provided
com.fasterxml.jackson.core
jackson-databind
2.9.6
dom4j
dom4j
1.6.1
jaxen
jaxen
1.1.6
cglib
cglib
2.1_2
```
- 创建数据库外部配置文件 jdbc.properties
```
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ozdemo?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
```
- 创建数据库表
```
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`aid` int(11) NOT NULL AUTO_INCREMENT,
`cardNo` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`money` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`aid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, '6029621011001', '韩梅梅', 10000);
INSERT INTO `account` VALUES (2, '6029621011000', '李大雷', 10000);
SET FOREIGN_KEY_CHECKS = 1;
```
- 创建必要的注解类 @Service、@Autowired、@Transactional、@Bean、@Value、@Component等
@Transactional示例:其它类似
```
/**
* @Description: @Transactional注解
* @Author: Created by OrangeZh
* @Date: Created in 2020/9/4 17:37
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
String value() default "";
String transactionManager() default "";
}
```
- **(AOP关建代码)创建动态代理工厂类 ProxyFactory和事务类 TransactionManager**
```
/**
* 代理对象工厂:生成代理对象的
*/
@Component("proxyFactory")
public class ProxyFactory {
@Autowired
private TransactionManager transactionManager;
/**
* Jdk动态代理
*
* @param obj 委托对象
* @return 代理对象
*/
public Object getJdkProxy(Object obj) {
// 获取代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
// 开启事务(关闭事务的自动提交)
transactionManager.beginTransaction();
result = method.invoke(obj, args);
// 提交事务
transactionManager.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
transactionManager.rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
return result;
}
});
}
/**
* 使用cglib动态代理生成代理对象
*
* @param obj 委托对象
* @return
*/
public Object getCglibProxy(Object obj) {
return Enhancer.create(obj.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
try {
// 开启事务(关闭事务的自动提交)
transactionManager.beginTransaction();
result = method.invoke(obj, objects);
// 提交事务
transactionManager.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
transactionManager.rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
return result;
}
});
}
}
/**
* 事务管理器类:负责手动事务的开启、提交、回滚
*/
@Component("transactionManager")
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
// 开启手动事务控制
public void beginTransaction() throws SQLException {
connectionUtils.getCurrentThreadConn().setAutoCommit(false);
}
// 提交事务
public void commit() throws SQLException {
connectionUtils.getCurrentThreadConn().commit();
}
// 回滚事务
public void rollback() throws SQLException {
connectionUtils.getCurrentThreadConn().rollback();
}
}
```
- **(IOC关建代码)创建BeanFactory IOC容器 bean工厂**
```
/**
* @Description: IOC容器 bean工厂
* @Author: Created by OrangeZh
* @Date: Created in 2020/9/4 15:15
*/
public class BeanFactory {
//外部配置文件配置信息
private static Properties properties = new Properties();
private static final String classpath = BeanFactory.class.getResource("/").getPath();
//bean定义Map 处理存放bean的基本信息
private static Map> beanDefinitionMap = new ConcurrentHashMap<>();
//缓存bean 容器缓存(单例缓存池)
private static ConcurrentHashMap beanMap = new ConcurrentHashMap<>();
//扫描到的所有类
private static List> classList = new ArrayList<>();
static {
initIoc();
}
/**
* 初始化容器
* 1、获取配置文件配置内容
* 2、配置类(AppConfig)解析
* 3、扫描包下的所有类
* 4、遍历所有类,并放入到beanDefinitionMap中
* 5、实例化并初始化所有bean
*/
private static void initIoc() {
try {
//1、获取配置文件配置内容
properties = getProperties("jdbc.properties");
//2、配置类解析
Class> configClass = AppConfig.class;
String configBeanName = Introspector.decapitalize(configClass.getSimpleName());
beanDefinitionMap.put(configBeanName, configClass);
String[] scanPackages = configClass.getAnnotation(ComponentScan.class).value();
//3、加载包下的所有类
if (scanPackages.length > 0) {
for (String scanPackage : scanPackages) {
getAllClasses(scanPackage, classList);
}
} else {
getAllClasses("", classList);
}
//4、遍历所有类,并放入到beanDefinitionMap中
if (classList.size() > 0) {
for (Class> clazz : classList) {
String beanName = Introspector.decapitalize(clazz.getSimpleName());
//类注解
if (clazz.isAnnotationPresent(Component.class)) {
Component annotation = clazz.getAnnotation(Component.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
} else if (clazz.getInterfaces().length > 0) {
beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName());
}
} else if (clazz.isAnnotationPresent(Service.class)) {
Service annotation = clazz.getAnnotation(Service.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
} else if (clazz.getInterfaces().length > 0) {
beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName());
}
} else if (clazz.isAnnotationPresent(Repository.class)) {
Repository annotation = clazz.getAnnotation(Repository.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
}
} else {
continue;
}
beanDefinitionMap.put(beanName, clazz);
}
}
//5、实例化并初始化所有bean
//先初始化配置类
getBean(configBeanName);
for (String beanName : beanDefinitionMap.keySet()) {
getBean(beanName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建bean
* 1、实例化Bean
* 2、初始化Bean
*
* @param beanName
* @throws Exception
*/
private static Object doCreateBean(String beanName) throws Exception {
Object bean = beanMap.get(beanName);
if (bean != null) {
return bean;
}
createBeanInstance(beanName);
populateBean(beanName);
return beanMap.get(beanName);
}
/**
* 实例化Bean
*
* @param beanName
* @throws Exception
*/
private static void createBeanInstance(String beanName) throws Exception {
Class> clazz = beanDefinitionMap.get(beanName);
//实例化
Object bean = clazz.newInstance();
if (clazz.isAnnotationPresent(Transactional.class)) {
//转为代理对象
ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory");
if (clazz.getInterfaces().length > 0) {
bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象
} else {
bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象
}
}
beanMap.put(beanName, bean);
}
/**
* 初始化Bean
* 解析 @Autowired、@Value、@Transactional等注解
*
* @param beanName
*/
private static void populateBean(String beanName) throws Exception {
Object bean = getBean(beanName);
Class extends Object> clazz = bean.getClass();
//自动注入
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Autowired.class)) {
//Autowired autowiredAnno = field.getAnnotation(Autowired.class);
//通过属性名称 获取bean
Object value = getBean(field.getName());
field.setAccessible(true);
//给属性赋值
field.set(bean, value);
} else if (annotation.annotationType().equals(Value.class)) {
Value valueAnno = field.getAnnotation(Value.class);
String value = valueAnno.value();
if (value.startsWith("${") && value.endsWith("}")) {
value = properties.getProperty(value.split("\\$\\{")[1].split("}")[0]);
}
field.setAccessible(true);
//给属性赋值
field.set(bean, value);
}
}
}
//方法注解
Method[] methods = clazz.getMethods();
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Transactional.class)) {
//转为代理对象
ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory");
Class>[] cl = clazz.getInterfaces();
if (clazz.getInterfaces().length > 0) {
bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象
} else {
bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象
}
beanMap.put(beanName, bean);
} else if (annotation.annotationType().equals(Bean.class)) {
Bean beanAnno = method.getAnnotation(Bean.class);
Class> returnClass = method.getReturnType();
String beanName1 = Introspector.decapitalize(returnClass.getSimpleName());
if (!beanAnno.value().equals("")) {
beanName1 = beanAnno.value();
}
//获取方法执行返回的对象,返回的就是bean
Object beanClass = method.invoke(bean);
beanMap.put(beanName1, beanClass);
}
}
}
}
/**
* 获取bean
*
* @param beanName
* @return
*/
public static Object getBean(String beanName) throws Exception {
Object bean = beanMap.get(beanName);
if (bean == null) {
bean = doCreateBean(beanName);
}
return bean;
}
/**
* 获取某个包下的所有类
*
* @param classes 存放类的list
* @param packageName 包名
* @return
*/
private static void getAllClasses(String packageName, List> classes) {
try {
//将包名转换为路径
String path = classpath + packageName.replaceAll("\\.", Matcher.quoteReplacement(File.separator));
File file = new File(path);
File[] fileList = file.listFiles();
if (null != fileList && fileList.length > 0) {
for (File curFile : fileList) {
if (curFile.isFile()) {
System.out.println("file is:" + curFile);
System.out.println(packageName + "." + curFile.getName().split("\\.")[0]);
Class> aClass = Class.forName(packageName + "." + curFile.getName().split("\\.")[0]);
classes.add(aClass);
}
if (curFile.isDirectory()) {
System.out.println("dir is :" + curFile);
getAllClasses(packageName + "." + curFile.getName(), classes);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读取配置文件
*
* @return
*/
private static Properties getProperties(String... files) {
Properties properties = new Properties();
try {
if (files.length > 0) {
for (String file : files) {
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
properties.load(inputStreamReader);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Get properties is fail!");
}
return properties;
}
```
- 项目源码 [https://gitee.com/orangezh/OZAnnoIocDemo](https://gitee.com/orangezh/OZAnnoIocDemo)
#### Spring源码构建
- 下载源码(github)
- 安装gradle 5.6.3(类似于maven) Idea Jdk 8+
- 导⼊(耗费⼀定时间)
- 编译⼯程(顺序:core-oxm-context-beans-aspects-aop)
`⼯程—>tasks—>compileTestJava`
- 运行可能出现的错误:[https://zhuanlan.zhihu.com/p/86606269?from_voters_page=true](https://zhuanlan.zhihu.com/p/86606269?from_voters_page=true)
#### Spring IOC源码分析
1、进入源码前准备TestBean和测试用例 此次源码分析主要以Bean初始化为主线
```
public class ItBean {
private TestBean testBean;
public void setLagouBean(TestBean testBean) {
this.testBean = testBean;
}
/**
* 构造函数
*/
public ItBean(){
System.out.println("ItBean 构造器...");
}
}
public class TestBean implements InitializingBean, ApplicationContextAware {
private ItBean itBean;
public void setItBean(ItBean itBean) {
this.itBean = itBean;
}
/**
* 构造函数
*/
public TestBean(){
System.out.println("TestBean 构造器...");
}
}
```
2、ClasspathXmlApplicationContext 为例,进入源码流程
```
/**
* ApplicationContext是容器的高级接口,BeanFactory(顶级容器/根容器,规范了/定义了容器的基础行为)
* Spring应用上下文,官方称之为 IoC容器(错误的认识:容器就是map而已;准确来说,map是ioc容器的一个成员,叫做单例池, singletonObjects,容器是一组组件和过程的集合,包括BeanFactory、单例池、BeanPostProcessor等以及之间的协作流程)
*
* Ioc容器创建管理Bean对象的,Spring Bean是有生命周期的
* 构造器执行、初始化方法执行、Bean后置处理器的before/after方法、:AbstractApplicationContext#refresh#finishBeanFactoryInitialization
* Bean工厂后置处理器初始化、方法执行:AbstractApplicationContext#refresh#invokeBeanFactoryPostProcessors
* Bean后置处理器初始化:AbstractApplicationContext#refresh#registerBeanPostProcessors
*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestBean testBean = applicationContext.getBean(TestBean.class);
```
3、在TestBean 构造器方法处打断点,看在哪个方法对Bean进行了初始化

由上图可看出调用的方法路径
4、org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
```
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
super(parent);
setConfigLocations(configLocations);
//是否刷新容器
if (refresh) {
//初始化容器
refresh();
}
}
```
5、org.springframework.context.support.AbstractApplicationContext#refresh
```Java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第⼀步:刷新前的预处理
prepareRefresh();
// 第⼆步:获取BeanFactory;默认实现是DefaultListableBeanFactory,加载BeanDefinition 并注册到 BeanDefinitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等)
prepareBeanFactory(beanFactory);
try {
// 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
postProcessBeanFactory(beanFactory);
// 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏
registerBeanPostProcessors(beanFactory);
// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 第⼋步:初始化事件派发器
initApplicationEventMulticaster();
// 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
registerListeners();
// 第⼗⼀步:初始化所有的⾮懒加载的单例bean实例(未设置属性)
//填充属性
//初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
//调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
finishBeanFactoryInitialization(beanFactory);
// 第⼗⼆步:完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件(ContextRefreshedEvent)
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
```
6、org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization **初始化Bean**
```
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化所有剩余(非惰性init)单例
beanFactory.preInstantiateSingletons();
}
```
7、org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons **实例化所有剩余(非惰性init)单例**
```
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// 实例化所有剩余的(非延迟初始化)单例Bean,beanDefinitionNames在创建BeanFactory时就缓存了
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断是否是非抽象类,是否是单例,是否是非懒加载
if (isFactoryBean(beanName)) { //判断是否是FactoryBean,是的话要加 & 前缀获取
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean> factory = (FactoryBean>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else { //获取Bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction