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容器实现。

posted @ 2017-04-18 13:01  Lucare  阅读(181)  评论(0编辑  收藏  举报