# 手写Spring框架 **Repository Path**: alizipeng/handwriting-spring-framework ## Basic Information - **Project Name**: 手写Spring框架 - **Description**: 手写Spring框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-08-17 - **Last Updated**: 2023-11-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1. Bean扫描 ## 1.1 核心注解 ### 1.1.1 @Component ```java package com.zipeng.spring.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解用途:标注一个类为组件 * * 可以保留到运行时 * 目标对象为类 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Component { String value() default ""; } ``` ### 1.1.2 @ComponentScan ```java package com.zipeng.spring.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解用途:设置组件扫描的路径 * * 可以保留到运行时 * 可以作用在类上 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ComponentScan { String value(); } ``` ### 1.1.3 @Scope ```java package com.zipeng.spring.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 声明Bean的作用域 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Scope { String value(); } ``` ## 1.2 BeanDefinition ```java package com.zipeng.spring.core; /** * Bean定义类 */ public class BeanDefinition { private Class clazz; private String scope; public BeanDefinition() { } public BeanDefinition(Class clazz, String scope) { this.clazz = clazz; this.scope = scope; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } } ``` ## 1.3 配置类AppConfig ```java package com.zipeng.test; import com.zipeng.spring.annotation.ComponentScan; @ComponentScan("com.zipeng.service") public class AppConfig { } ``` ## 1.4 核心上下文 ```java package com.zipeng.spring; import com.zipeng.spring.annotation.Component; import com.zipeng.spring.annotation.ComponentScan; import com.zipeng.spring.annotation.Scope; import com.zipeng.spring.core.BeanDefinition; import java.io.File; import java.net.URL; import java.util.concurrent.ConcurrentHashMap; public class MyApplicationContext { /** * 容器配置类 */ private Class configClass; /** * 存储 单例Bean 的容器 */ private ConcurrentHashMap singletonObjects = new ConcurrentHashMap<>(); /** * 存储 Bean定义 的容器 */ private ConcurrentHashMap beanDefinitionMap = new ConcurrentHashMap<>(); public MyApplicationContext(Class configClass) { this.configClass = configClass; // 1. 根据配置类,扫描组件,生成 BeanDefinition scan(configClass); // 2. 根据 beanDefinitionMap 把所有的单列 Bean 都实例化到 单例池 for(String beanName: beanDefinitionMap.keySet()){ // 2.1 获取 beanDefinition BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); // 2.2 判断是否为单例 if(beanDefinition.getScope().equals("singleton")){ // 2.2.1 创建 bean Object bean = createBean(beanDefinition); // 2.2.2 把bean放入单例池 singletonObjects.put(beanName, bean); } } } private Object createBean(BeanDefinition beanDefinition){ try { return beanDefinition.getClazz().newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } /** * 根据配置类,扫描组件,生成 BeanDefinition * @param configClass */ private void scan(Class configClass) { // 1.解析配置类 // 1.1 解析ComponentScan注解 ComponentScan componentScanAnnotation = (ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class); // 1.2 获得扫描路径 path String path = componentScanAnnotation.value(); // 1.3 获取扫描路径下的 Component // 1.3.1 获取类加载器 ClassLoader classLoader = MyApplicationContext.class.getClassLoader(); // 1.3.2 获取资源的URL URL resource = classLoader.getResource(path.replace(".", "/")); // 1.3.3 把URL转为一个文件 File file = new File(resource.getFile()); // 1.3.4 判断是否为一个目录 if(file.isDirectory()){ // 1.3.4.1 获取目录下的所有文件 File[] files = file.listFiles(); // 1.3.4.2 遍历数组进行逐个加载 for(File item: files){ // 1.3.4.2.1 构造类的全限定名 String className = path + "." + item.getName().substring(0, item.getName().lastIndexOf(".")); try { // 1.3.4.2.2 使用类加载器进行加载 Class aClass = classLoader.loadClass(className); // 1.3.4.2.3 判断该类是否存在 Component 注解 if(aClass.isAnnotationPresent(Component.class)){ // 1.3.4.2.3.1 获取 Component 注解 Component componentAnnotation = aClass.getDeclaredAnnotation(Component.class); // 1.3.4.2.3.2 获取 beanName String beanName = componentAnnotation.value(); // 1.3.4.2.3.3 构造 BeanDefinition BeanDefinition beanDefinition = new BeanDefinition(); if(aClass.isAnnotationPresent(Scope.class)){ Scope scope = aClass.getDeclaredAnnotation(Scope.class); beanDefinition.setScope(scope.value()); }else{ beanDefinition.setScope("singleton"); } beanDefinition.setClazz(aClass); // 1.3.4.2.3.4 把 BeanDefinition 存储到 map beanDefinitionMap.put(beanName, beanDefinition); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } public Object getBean(String beanName){ // 1. 判断Bean对象是否存在 map if (beanDefinitionMap.containsKey(beanName)){ // 1.1 获取 BeanDefinition BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); // 1.2 判断该 Bean 的作用域是否为单列 if(beanDefinition.getScope().equals("singleton")){ // 1.2.1 直接从单列池中获取 Bean return singletonObjects.get(beanName); }else { // 1.2.2 如果是原型 bean 直接创建新的对象 return createBean(beanDefinitionMap.get(beanName)); } } // 2. 不存在对应的 Bean,抛出异常 throw new IllegalArgumentException("不存在对应的 Bean"); } } ``` ## 1.5 测试 ```java package com.zipeng.test; import com.zipeng.spring.MyApplicationContext; public class Test { public static void main(String[] args) { MyApplicationContext myApplicationContext = new MyApplicationContext(AppConfig.class); System.out.println(myApplicationContext.getBean("userService")); System.out.println(myApplicationContext.getBean("userService")); System.out.println(myApplicationContext.getBean("userService")); } } ``` ``` com.zipeng.service.UserService@5e2de80c com.zipeng.service.UserService@5e2de80c com.zipeng.service.UserService@5e2de80c ``` # 2. 依赖注入 ## 2.1 @Autowired ```java package com.zipeng.spring.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自动注入注解 * * 生命周期:运行时 * 作用对象:方法、字段 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD}) public @interface Autowired { } ``` ## 2.2 修改核心上下文的createBean方法 ```java private Object createBean(BeanDefinition beanDefinition){ // 1. 获取对应类对象 Class clazz = beanDefinition.getClazz(); try { // 2. 实例化对象 Object instance = clazz.newInstance(); // 3. 依赖注入 for (Field declaredField : clazz.getDeclaredFields()) { // 3.1 判断该字段是否需要注入 if(declaredField.isAnnotationPresent(Autowired.class)){ // 3.1.1 获取 bean Object bean = getBean(declaredField.getName()); // 3.1.2 设置该字段可访问 declaredField.setAccessible(true); // 3.1.3 注入 declaredField.set(instance, bean); } } return instance; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } ``` ## 2.3 测试 ```java package com.zipeng.service; import com.zipeng.spring.annotation.Autowired; import com.zipeng.spring.annotation.Component; @Component("userService") public class UserService { @Autowired private OrderService orderService; public void testAutowired(){ System.out.println(orderService); } } ``` ```java public class Test { public static void main(String[] args) { MyApplicationContext myApplicationContext = new MyApplicationContext(AppConfig.class); UserService userService = (UserService) myApplicationContext.getBean("userService"); userService.testAutowired(); } } ``` ``` com.zipeng.service.OrderService@5e481248 ``` # 3. Aware回调 ## 3.1 BeanNameAware接口 ```java package com.zipeng.spring.myinterface; public interface BeanNameAware { void setBeanName(String beanName); } ``` ## 3.2 实现接口 ```java package com.zipeng.service; import com.zipeng.spring.annotation.Autowired; import com.zipeng.spring.annotation.Component; import com.zipeng.spring.myinterface.BeanNameAware; import com.zipeng.spring.myinterface.InitializingBean; @Component("userService") public class UserServiceImpl implements BeanNameAware, UserService { @Autowired private OrderService orderService; private String beanName; public void testAutowired(){ System.out.println(orderService); } @Override public void setBeanName(String beanName) { this.beanName = beanName; } } ``` ## 3.3 修改创建Bean方法 ```java private Object createBean(String beanName, BeanDefinition beanDefinition){ // 1. 获取对应类对象 Class clazz = beanDefinition.getClazz(); try { // 2. 实例化对象 Object instance = clazz.newInstance(); // 3. 依赖注入 for (Field declaredField : clazz.getDeclaredFields()) { // 3.1 判断该字段是否需要注入 if(declaredField.isAnnotationPresent(Autowired.class)){ // 3.1.1 获取 bean Object bean = getBean(declaredField.getName()); // 3.1.2 设置该字段可访问 declaredField.setAccessible(true); // 3.1.3 注入 declaredField.set(instance, bean); } } // 4. 判断是否实现了BeanNameAware接口 if(instance instanceof BeanNameAware){ ((BeanNameAware) instance).setBeanName(beanName); } return instance; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } ``` # 4. 初始化 ## 4.1 InitializingBean接口 ```java package com.zipeng.spring.myinterface; public interface InitializingBean { void afterPropertiesSet() throws Exception; } ``` ## 4.2 实现接口 ```java package com.zipeng.service; import com.zipeng.spring.annotation.Autowired; import com.zipeng.spring.annotation.Component; import com.zipeng.spring.myinterface.BeanNameAware; import com.zipeng.spring.myinterface.InitializingBean; @Component("userService") public class UserServiceImpl implements BeanNameAware, InitializingBean, UserService { @Autowired private OrderService orderService; private String beanName; public void testAutowired(){ System.out.println(orderService); } @Override public void setBeanName(String beanName) { this.beanName = beanName; } @Override public void afterPropertiesSet() throws Exception { System.out.println("初始化,自定义逻辑。。。"); } } ``` ## 4.3 修改创建Bean方法 ```java private Object createBean(String beanName, BeanDefinition beanDefinition){ // 1. 获取对应类对象 Class clazz = beanDefinition.getClazz(); try { // 2. 实例化对象 Object instance = clazz.newInstance(); // 3. 依赖注入 for (Field declaredField : clazz.getDeclaredFields()) { // 3.1 判断该字段是否需要注入 if(declaredField.isAnnotationPresent(Autowired.class)){ // 3.1.1 获取 bean Object bean = getBean(declaredField.getName()); // 3.1.2 设置该字段可访问 declaredField.setAccessible(true); // 3.1.3 注入 declaredField.set(instance, bean); } } // 4. 判断是否实现了BeanNameAware接口 if(instance instanceof BeanNameAware){ ((BeanNameAware) instance).setBeanName(beanName); } // 5. 初始化 if(instance instanceof InitializingBean){ try { ((InitializingBean) instance).afterPropertiesSet(); } catch (Exception e) { e.printStackTrace(); } } return instance; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } ``` # 5. BeanPostProcessor ## 5.1 BeanPostProcessor接口 ```java package com.zipeng.spring.myinterface; public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName); Object postProcessAfterInitialization(Object bean, String beanName); } ``` ## 5.2 添加BeanPostProcessor容器 ```java /** * 存储 beanPostProcessor */ private List beanPostProcessorList = new ArrayList<>(); ``` ## 5.3 实现接口 ```java package com.zipeng.service; import com.zipeng.spring.MyApplicationContext; import com.zipeng.spring.annotation.Component; import com.zipeng.spring.myinterface.BeanPostProcessor; import java.lang.reflect.Proxy; @Component("myBeanPostProcessor") public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if(beanName.equals("userService")){ ((UserServiceImpl)bean).setTestBeanPostProcessor("测试BeanPostProcessor"); } System.out.println("初始化前,执行自定义逻辑"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("初始化后,执行自定义逻辑"); if("userService".equals(beanName)){ Object proxyInstance = Proxy.newProxyInstance(MyApplicationContext.class.getClassLoader(), bean.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("代理逻辑"); return method.invoke(bean, args); }); return proxyInstance; } return bean; } } ``` ## 5.3 修改创建Bean方法 ```java private Object createBean(String beanName, BeanDefinition beanDefinition){ // 1. 获取对应类对象 Class clazz = beanDefinition.getClazz(); try { // 2. 实例化对象 Object instance = clazz.newInstance(); // 3. 依赖注入 for (Field declaredField : clazz.getDeclaredFields()) { // 3.1 判断该字段是否需要注入 if(declaredField.isAnnotationPresent(Autowired.class)){ // 3.1.1 获取 bean Object bean = getBean(declaredField.getName()); // 3.1.2 设置该字段可访问 declaredField.setAccessible(true); // 3.1.3 注入 declaredField.set(instance, bean); } } // 4. 判断是否实现了BeanNameAware接口 if(instance instanceof BeanNameAware){ ((BeanNameAware) instance).setBeanName(beanName); } // 5. 初始化前:调用 postProcessBeforeInitialization for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName); } // 6. 初始化 if(instance instanceof InitializingBean){ try { ((InitializingBean) instance).afterPropertiesSet(); } catch (Exception e) { e.printStackTrace(); } } // 7. 初始化后:调用 postProcessAfterInitialization for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName); } return instance; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } ``` # 6. 实现AOP ```java package com.zipeng.service; import com.zipeng.spring.MyApplicationContext; import com.zipeng.spring.annotation.Component; import com.zipeng.spring.myinterface.BeanPostProcessor; import java.lang.reflect.Proxy; @Component("myBeanPostProcessor") public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if(beanName.equals("userService")){ ((UserServiceImpl)bean).setTestBeanPostProcessor("测试BeanPostProcessor"); } System.out.println("初始化前,执行自定义逻辑"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("初始化后,执行自定义逻辑"); if("userService".equals(beanName)){ Object proxyInstance = Proxy.newProxyInstance(MyApplicationContext.class.getClassLoader(), bean.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("代理逻辑"); return method.invoke(bean, args); }); return proxyInstance; } return bean; } } ```