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 {@
    Override
    public Object postProcessorBeforeInitialization(String beanName, Object bean) {
        if (beanName.equals("userService")) {
            System.out.println("处理 userService 初始化之前 ...");
        }
        return bean;
    }

    @Override
    public 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() {@
                    Override
                    public 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 {@
    Autowired
    private OrderService orderService;

    public void print() {
        System.out.println(orderService);
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("beanName ==> " + beanName);
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService 初始化后其他操作 ...");
    }

    @Override
    public 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\service
            File 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);
                            // 获取 BeanName
                            String beanName = componentAnnotation.value().equals("") ? Introspector.decapitalize(clazz.getSimpleName()) : componentAnnotation.value();
                            // 定义 Bean
                            BeanDefinition beanDefinition = new BeanDefinition();
                            // 定义 Bean 的类型
                            beanDefinition.setType(clazz);
                            // 定义 Bean 的范围
                            if (clazz.isAnnotationPresent(Scope.class)) {
                                Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                beanDefinition.setScope(scopeAnnotation.value());
                            } else { // 单例 Bean
                                beanDefinition.setScope(BeanScope.sigleton.toString());
                            }
                            // 将定义后的 Bean 存入到单例池
                            beanDefinitionMap.put(beanName, beanDefinition);
                        }
                    }
                }
            }
        }

        // 实例化单例 Bean
        for (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())) { // 单例 Bean
            Object bean = singletonObjects.get(beanName);
            if (null == bean) {
                singletonObjects.put(beanName, createBean(beanName, beanDefinition));
            }
            return bean;
        } else { // 多例 Bean
            return 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();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值