zoukankan      html  css  js  c++  java
  • Spring学习的切入点

    spring是个顶级的框架,这话没毛病。很多人想把它征服,想去阅读它的源码,弄懂它的设计思想,从中学到精粹。

    但是很多次打开后,看到庞大的体系结构,就懵逼了,不知从何入手。

    我在这里总结下学习spring的切入点:

    • IOC
      控制反转,是spring的核心吧,对于bean的生面周期的管理。

    • AOP
      面向切面编程,基于JDK动态代理和cglib字节码实现。

    首先从IOC开始吧,控制反转,就是将对象的创建转移给框架,不需要你去new,你只需要通过配置或者注解来让它知道从哪入手。这样做有什么好处?

    1. 不用再编写创建对象的代码和维持其复杂的依赖关系。
    2. 定义一个接口,可以方便更改其实现类,或者注入需要的属性。

    然后就是自己写个简单的接口和实现,开始debug,通过xml配置的方式来注入bean:

    <bean id="test" class="com.fcs.xmls.TestBean">
        <!-- 配置属性phone -->
        <property name="phone" value="15507516532"></property>
        <!-- 配置属性age,虽然此处是字符串“25”,但是Spring会识别age的类型,然后把字符串“14”转变后赋值给age -->
        <property name="age" value="25"></property>
    </bean>

    用下面的方式获取bean:

    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    TestBean t = (TestBean) ac.getBean("test");

    用idea弄个类继承关系图:
    这里写图片描述

    可以看到BeanFactory,从命名可以看出来这是个工厂模式,所以从这里你需要了解工厂模式(工厂方法模式)。

    在跟踪的过程中,很容易就跳到了AbstractApplicationContext 中的refresh 方法,在这个方法做了一系列操作:

        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    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();
                }
            }
        }

    同样,用注解来一波:

    @Component
    public class MessagePrinter {
    
        final private MessageService service;
    
        @Autowired
        public MessagePrinter(MessageService service) {
            this.service = service;
        }
    
        public void printMessage() {
            System.out.println(this.service.getMessage());
        }
    
    }
    ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
    MessagePrinter printer = context.getBean(MessagePrinter.class);

    也可得到下图:
    这里写图片描述

    两者的上层结构基本相同,分离点也在AbstractApplicationContext ,各自有了不同的扩展。所以重点还是在AbstractApplicationContext 的refresh 方法。

    这里可以看到第二个模式:模板方法模式。在AbstractApplicationContext 中定义算法簇,子类做不同的具体实现。

    这就是切入点了。只是简单的分析下,细节还得去看,如果看不下去,还得学习设计模式。此外思想可以参考spring-tiny,一个简单的ioc容器实现。

    ================================== 赵客缦胡缨,吴钩霜雪明。 银鞍照白马,飒沓如流星。 ==================================
  • 相关阅读:
    python 查询文件存放地址
    类数组对象:arguments
    前端开发工程师从入门到精通学习过程及资源总结(持续更新中)
    CSS3的圆角border-radius属性
    内联元素inline-block空隙问题
    js中typeof用法详细介绍
    正则表达式
    sublime text 3 快捷键大全以及配置编译环境
    c# 泛型类
    c# 中config.exe 引发的一些问题
  • 原文地址:https://www.cnblogs.com/lucare/p/9312655.html
Copyright © 2011-2022 走看看