美文网首页Spring
Spring的杂谈上

Spring的杂谈上

作者: 沈先生的影子 | 来源:发表于2020-11-06 17:21 被阅读0次

    什么是Spring框架?Spring框架有哪些主要的模块?

      Spring框架是一个开放源代码的J2EE应用程序框架、是针对bean的生命周期进行管理的轻量级容器。

      1.Spring框架是一个为J2EE的开发提供综合、广泛的基础性支持的Java平台。
      2.Spring帮助开发者解决了开发中的基础问题,让开发者可以专注于应用程序的开发。
      3.Spring框架是非入侵式的框架,底层是依照设计模式精心打磨的框架,这让我们可以在开发环境中安心的使用,无须操心Spring在后台是如何工作的。
      4.Spring框架主要由七部分组成。如: Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC,为我们开发提供了较多的脚手架。

    使用Spring可以带来哪些好处?

    1.方便解耦,简化开发
      Spring提供了IOC容器,让对象之间的依赖关系由Spring进行控制,避免了硬编码带来的过度耦合,使得用户无需关心类的作用域、属性文件解析的底层代码,专注于上层应用。

    2.AOP编程的支持
      通过Spring的AOP功能,更方便的面向切面编程,使得有些功能在OOP层面难以做到,可以通过AOP轻松完成。

    3.声明式事务管理
      通过声明式方式灵活地进行事务的管理,将一些通用任务如安全、事务、日志等进行集中式管理,提高开发效率和质量。

    4.方便程序测试
      Spring对Junit4支持,可以通过注解方便的测试Spring程序。

    5.无缝集成各种优秀框架
      Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如ORM框架、LOGGING框架、Quartz)等的支持。

    6.降低Java EE API的使用难度
      Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

    7.Java 源码是经典学习范例
      提供了各种设计模式的实现,让我受益匪浅。

    8.轻量级非入侵式
      与EJB容器相比较,IOC容器较为轻量级,可以在节省内存和CPU资源的消耗。

    什么是IOC和DI?

    IOC(Inversion Of Control) 控制反转:
      所谓的控制反转,就是把代码里需要实现对象创建、依赖的代码,反转给容器来实现。

    DI(Dependency Injection)依赖注入:
      对象被动接受依赖类不需要自己实例或者寻找,简单来说就是对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将其依赖的类注入。

    Java 中依赖注入哪三种实现方式?

      1.构造器
      2.setter方法注入
      3.接口注入

    请解释下 Spring 框架中的 IOC?

      IOC的中文意思就是控制反转,就是把代码里需要实现对象创建、依赖的代码,反转给容器来实现。

      IOC其实是一种编程思想的体现,以往应用程序获取对象都是“\color{red}{主动}”获取new Object(),而IOC/DI出现之后我们由“\color{red}{主动}”变为“\color{red}{被动}”,所有需要注入的对象由IOC/DI进行注入。

    具体是怎么实现的呢?

      IOC本质上是一个容器,用于存储所有被Spring管理的Bean。

    具体实现:
      这个要从IOC容器初始化去一步一步了解,IOC初始化会经历三个步骤,定位、加载、注册三步。

    定位阶段(我们知道 Bean是由Spring IOC容器中存储的吧,可是我去哪里找这些Bean呢?对象和对象的关系如何表示?这个时候需要我们告诉Spring 我们需要被管理的类在哪里?)

      描述对象之间的关系文件一般是:yml、xml、properties等。

      描述对象关系文件一般存储在:classpath、filesystem、URL网络资源、servletContext等。

      例如是 xml文件的读取,通过ApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”);告诉Spring 描述对象之间关系的文件在这里,Spring表示知道了文件的地方然后调用setConfigLocations(configLocations);方法解析Bean定义资源文件的路径,然后调用AbstractApplicationContext.refresh()方法。

    加载阶段 (Spring现在知道了,需要被管理的类在哪个地方了,可是IOC还没有进行初始化,什么时候进行呢?Bean描述对象关系的内容被存储在哪里呢?然后Bean文件怎么被读取呢?)

      AbstractApplicationContext.refresh()里调用方法ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 这里获得一个BeanFactroy工厂,IOC容器在这里完成了初始化。有人会问了,BeanFactory就是IOC容器吗?我可以告诉你,是的,里面包含了存储Bean的容器。
      现在我们的IOC容器初始化完成,这个时候需要对xml配置的bean描述文件进行加载,在Spring中,所有的描述对象关系的文件都会被保存为BeanDefinition,在obtainFreshBeanFactory()真正的实现类里会调用AbstractXmlApplicationContext.loadBeanDefinitions(beanFactory);方法去载入。
      用什么去读取xml文件呢?使用InputStream 使用文件IO流读入将XML文件转换为DOM对象,解析过程由doLoadDocument(inputSource, resource);实现。主要这个DOM对象不是Spring内部的DOM对象,得到这个DOM之后,还要继续去调用子类,按照Spring的Bean语义要求将Bean定义资源解析并转换为容器内部数据结构,具体调用registerBeanDefinitions(Document doc, Resource resource);进行Bean 的加载,(这个时候还没有进行注册/初始化)。

    注册阶段(我们的Bean是怎么被解析的,被谁解析,被注册成什么了?)

      我们的bean文件,具体是被BeanDefinitionParserDelegate进行解析,具体是怎么样的呢,在加载阶段获得的DOM对象获取到具体需要被扫描的Bean的文件路径,然后通过文件流的方式进行读取解析。
      解析的过程非常复杂,我就不去深究了,解析完成的得到BeanDefinition,通过BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());向IOC容器注册解析Bean,最后得到beanDefinitionMap。

    BeanFactory和ApplicationContext的区别?

      BeanFactory可以理解为含有bean集合的工厂类。BeanFactory包含了各种bean的定义,可以满足客户端请求对应的bean。

      ApplicationContext接口继承了ListableBeanFactory而ListableBeanFactory是BeanFactroy的具体实现,也就是说ApplicationContext里拥有了BeanFactory的功能。

      Spring中,ApplicationContext拥有了比BeanFactroy更多的功能,是一个更加高级的容器。比如:

    1. 国际化(MessageSource)

    2. 访问资源,如URL和文件(ResourceLoader)

    3. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层

    4. 消息发送、响应机制(ApplicationEventPublisher)

    Spring 有几种配置方式?

    1. 基于XML的配置 2. 基于注解的配置 3. 基于Java的配置

    如何使用xml来配置Spring框架?

    目的

      SpringXML 配置的主要目的是使得所有的Spring组件都可以通过XML文件进行配置。

    配置方式

      Spring的XML配置方式是使用命名空间所支持的XML标签来实现的
      Spring 有以下主要几个命名空间和组件:
        context、beans、jdbc、tx、aop、mvc 、aso

      下面这个web.xml,配置了DispatcherServlet,这件最简单的配置便能满足应用程序配置运行时组件的需求。

    
        <web-app>
            <display-name>Archetype Created Web Application</display-name>
            <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>
                org.springframework.web.servlet.DispatcherServlet
                        </servlet-class>
            <load-on-startup>1</load-on-startup>
            </servlet>
            <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>/</url-pattern>
            </servlet-mapping>
        </web-app>
    
    

    如何通过Java配置的方式配置Spring?

      Spring对Java配置可以通过注解@Configuration@Bean来完成的。

    @Bean

      @Bean 标识一个用于配置和初始化一个由SpringIOC容器管理的新对象的方法,类似于XML配置文件的<bean/>,一般与@Configration注解配合使用

    @Configuration

      @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

    需要注意!需要注意! 需要注意!

    @Configuration不可以是final类型;

    @Configuration不可以是匿名类;

    嵌套的configuration必须是静态类。

    @Configuration
    public class AppConfig{
        @Bean
        public MyService myService() {
            return new MyServiceImpl();
        }
    }
    
    <beans>
            <bean id="myService" class="com.gupaoedu.services.MyServiceImpl"/>
    </beans>
    

    上述配置方式的实例化方式如下:利用 AnnotationConfigApplicationContext 类进行实例化

        public static void main(String[] args) {
            ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
            MyService myService = ctx.getBean(MyService.class);
            myService.doStuff();
        }
    

    要使用组件组建扫描,仅需用@Configuration 进行注解即可:

        @Configuration
        @ComponentScan(basePackages = "com.dia")
        public class AppConfig {
    
        }
    

      在上面的例子中,com.dia 包首先会被扫到,然后再容器内查找被@Component 声明的类,找到后将这些类按照 Sring bean 定义进行注册。

      如果你要在web应用开发中选中上述的配置方式,需要用AnnotationConfigWebApplicationContext 类来读取配置文件,可以用来配置 Spring 的Servlet 监听器 ContrextLoaderListener 或者 Spring MVC 的 DispatcherServlet。

    
    <web-app>
        <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
            instead of the default XmlWebApplicationContext -->
        <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
                    </param-value>
        </context-param>
        
        <!-- Configuration locations must consist of one or more comma- or space-delimited
            fully-qualified @Configuration classes. Fully-qualified packages may also be
            specified for component-scanning -->
        <context-param>
        
        
        <param-name>contextConfigLocation</param-name>
        
        <param-value>com.gupaoedu.AppConfig</param-value>
        </context-param>
        <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
        <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        
        <!-- Declare a Spring MVC DispatcherServlet as usual -->
        <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
            instead of the default XmlWebApplicationContext -->
        <init-param>
        
        <param-name>contextClass</param-name>
        
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
                    </param-value>
        </init-param>
        
        <!-- Again, config locations must consist of one or more comma- or space-delimited
            and fully-qualified @Configuration classes -->
        <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.gupaoedu.web.MVCConfig</param-value>
        </init-param>
        </servlet>
        
        <!-- map all requests for /web/* to the dispatcher servlet -->
        <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/web/*</url-pattern>
        </servlet-mapping>
    
    </web-app>
    
    

    用注解的方式配置 Spring?

      Spring在2.5版本后支持注解方式,可使用注解替代XML。注解装配在 Spring 中是默认关闭的。如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置:

        <beans>
            <context:annotation-config/>
            <!-- bean definitions go here -->
        </beans>
    

    在标签配置完成以后,就可以用注解的方式在 Spring 中向属性、方法和构造方法中自动装配变量。

    如果有兴趣可以去看看 Spring的常用注解

    相关文章

      网友评论

        本文标题:Spring的杂谈上

        本文链接:https://www.haomeiwen.com/subject/iiqzvktx.html