> 文章列表 > Spring基础总结(下)

Spring基础总结(下)

Spring基础总结(下)

简介

本章节通过手写一个简单的 Spring 框架来加深对 Spring 框架源码以及设计思想的理解;

实现步骤

  1. BeanScope 枚举代码
public enum BeanScope {    sigleton,    prototype;
}
  1. AppConfig 配置类
// 定义包扫描路径
@ComponentScan("com.dufu.spring")
public class AppConfig {}
  1. DufuBeanPostProcessor 后置处理器
@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;}
  1. UserService 接口代码
public interface IUserService {   void test();
}
  1. OrderService 实例
@Component
public class OrderService {}
  1. UserService 实例
@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() 方法");}
}
  1. Autowired 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {String value() default "";
}
  1. BeanDefinition Bean 的定义工具类
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;}
}
  1. BeanNameAware 回调接口
public interface BeanNameAware {    void setBeanName(String beanName);
}
  1. BeanPostProcessor 后置处理器接口
public interface BeanPostProcessor {    // 初始化前    Object postProcessorBeforeInitialization(String beanName, Object bean);    // 初始化后    Object postProcessorAfterInitialization(String beanName, Object bean);
}
  1. Component 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {String value() default "";
}
  1. ComponentScan 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {String value() default "";
}
  1. DufuApplicationContext Spring 容器核心设计
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 <String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap <> ();// Bean 单例池private ConcurrentHashMap <String, Object> 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);}}
}
  1. InitializingBean 初始化 Bean 接口
public interface InitializingBean {    void afterPropertiesSet();
}
  1. Scope 注解
@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();}
}