本章节通过手写一个简单的 Spring 框架来加深对 Spring 框架源码以及设计思想的理解;
public enum BeanScope { sigleton, prototype;
}
// 定义包扫描路径
@ComponentScan("com.dufu.spring")
public class AppConfig {}
@Component
public class DufuBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessorBeforeInitialization(String beanName, Object bean) {if (beanName.equals("userService")) {System.out.println("处理 userService 初始化之前 ...");}return bean;}@Overridepublic Object postProcessorAfterInitialization(String beanName, Object bean) {if (beanName.equals("userService")) {System.out.println("处理 userService 初始化之后 ...");// 创建代理对象,模拟 AOP 功能Object proxyInstance = Proxy.newProxyInstance(DufuBeanPostProcessor.class.getClassLoader(),bean.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("AOP 切面逻辑 ...");return method.invoke(bean, args);}});return proxyInstance;}return bean;}
public interface IUserService { void test();
}
@Component
public class OrderService {}
@Component
public class UserService implements BeanNameAware, InitializingBean, IUserService {@Autowiredprivate OrderService orderService;public void print() {System.out.println(orderService);}@Overridepublic void setBeanName(String beanName) {System.out.println("beanName ==> " + beanName);}@Overridepublic void afterPropertiesSet() {System.out.println("UserService 初始化后其他操作 ...");}@Overridepublic void test() {System.out.println("调用了 test() 方法");}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {String value() default "";
}
public class BeanDefinition {// Bean 的类型private Class type;// Bean 的范围(多例还是单例)private String scope;public Class getType() {return type;}public void setType(Class type) {this.type = type;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}
}
public interface BeanNameAware { void setBeanName(String beanName);
}
public interface BeanPostProcessor { // 初始化前 Object postProcessorBeforeInitialization(String beanName, Object bean); // 初始化后 Object postProcessorAfterInitialization(String beanName, Object bean);
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {String value() default "";
}
public class DufuApplicationContext {// 点符号private final String SYMBOL_SPOT = ".";// 左斜线private final String LEFT_SLASH = "/";// 右斜线private final String RIGHT_SLASH = "\\";// .class 后缀private final String SUFFIX_CLASS = ".class";// 配置类private Class configClass;// Bean 信息集合private ConcurrentHashMap beanDefinitionMap = new ConcurrentHashMap <> ();// Bean 单例池private ConcurrentHashMap singletonObjects = new ConcurrentHashMap <> ();// 后置处理器集合private List < BeanPostProcessor > beanPostProcessorList = new ArrayList <> ();public DufuApplicationContext() {}public DufuApplicationContext(Class configClass) throws Exception {this.configClass = configClass;// 判断有没有 @ComponentScan 注解, 并获取扫描路径,解析 Bean 对象信息if (configClass.isAnnotationPresent(ComponentScan.class)) {ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);String pkScanValue = componentScanAnnotation.value().equals("") ? configClass.getPackage().getName() : componentScanAnnotation.value();// 注意: 我们实际上需要的是 out 目录下的路径String packagePath = pkScanValue.replace(SYMBOL_SPOT, LEFT_SLASH);ClassLoader classLoader = DufuApplicationContext.class.getClassLoader();URL resource = classLoader.getResource(packagePath);// 得到本地项目的绝对路径// D:\sorftware\idea\workspace\workspace_11\spring-dufu\out\production\spring-dufu\com\dufu\serviceFile outDirectory = new File(resource.getFile());if (outDirectory.isDirectory()) {// 拿到所有编译后的 class 文件File[] files = outDirectory.listFiles();for (File file: files) {String filePath = file.getAbsolutePath();if (filePath.endsWith(SUFFIX_CLASS)) {String className = filePath.substring(filePath.lastIndexOf(RIGHT_SLASH) + 1, filePath.lastIndexOf(SUFFIX_CLASS));Class > clazz = classLoader.loadClass(pkScanValue + SYMBOL_SPOT + className);// 记录后置处理器if (BeanPostProcessor.class.isAssignableFrom(clazz)) {BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();beanPostProcessorList.add(instance);}// 声明为 Bean 的实体类if (clazz.isAnnotationPresent(Component.class)) {Component componentAnnotation = clazz.getAnnotation(Component.class);// 获取 BeanNameString beanName = componentAnnotation.value().equals("") ? Introspector.decapitalize(clazz.getSimpleName()) : componentAnnotation.value();// 定义 BeanBeanDefinition beanDefinition = new BeanDefinition();// 定义 Bean 的类型beanDefinition.setType(clazz);// 定义 Bean 的范围if (clazz.isAnnotationPresent(Scope.class)) {Scope scopeAnnotation = clazz.getAnnotation(Scope.class);beanDefinition.setScope(scopeAnnotation.value());} else { // 单例 BeanbeanDefinition.setScope(BeanScope.sigleton.toString());}// 将定义后的 Bean 存入到单例池beanDefinitionMap.put(beanName, beanDefinition);}}}}}// 实例化单例 Beanfor (String beanName: beanDefinitionMap.keySet()) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition.getScope().equals(BeanScope.sigleton.toString())) {Object bean = createBean(beanName, beanDefinition);singletonObjects.put(beanName, bean);}}}/*** 创建 Bean 对象*/private Object createBean(String beanName, BeanDefinition beanDefinition) throws Exception {Class clazz = beanDefinition.getType();// 利用初始化方法实例化对象Object instance = clazz.getConstructor().newInstance();// 依赖注入for (Field field: clazz.getDeclaredFields()) {// 如果属性上添加了 @Autowired 注解就注入if (field.isAnnotationPresent(Autowired.class)) {field.setAccessible(true);field.set(instance, getBean(field.getName()));}}// 如果实现了 BeanNameAware 接口, 回调方法if (instance instanceof BeanNameAware) {((BeanNameAware) instance).setBeanName(beanName);}// 后置处理器, 初始化前for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {instance = beanPostProcessor.postProcessorBeforeInitialization(beanName, instance);}// 初始化if (instance instanceof InitializingBean) {((InitializingBean) instance).afterPropertiesSet();}// BeanPostProcessor(Bean 的后置处理器) 初始化后 AOP// 后置处理器, 初始化后for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {instance = beanPostProcessor.postProcessorAfterInitialization(beanName, instance);}return instance;}/*** 根据名称获取 Bean*/public Object getBean(String beanName) throws Exception {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (null == beanDefinition) {throw new NullPointerException("名为: " + beanName + " 的 Bean 不存在");}String scope = beanDefinition.getScope();if (scope.equals(BeanScope.sigleton.toString())) { // 单例 BeanObject bean = singletonObjects.get(beanName);if (null == bean) {singletonObjects.put(beanName, createBean(beanName, beanDefinition));}return bean;} else { // 多例 Beanreturn createBean(beanName, beanDefinition);}}
}
public interface InitializingBean { void afterPropertiesSet();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope { String value() default "";
}
测试一下
public class Test {public static void main(String[] args) throws Exception {DufuApplicationContext context = new DufuApplicationContext(AppConfig.class);// 模拟依赖注入,Aware 回调,初始化//UserService userService = (UserService)context.getBean("userService");//System.out.println(userService);//userService.print();// 模拟 AOP 功能,调用前需要先注释掉上面的代码IUserService iUserService = (IUserService) context.getBean("userService");iUserService.test();}
}