美文网首页
Spring 介绍

Spring 介绍

作者: 王某某的笔记 | 来源:发表于2018-06-04 18:39 被阅读16次

    从这个地方随手翻译过来的
    https://www.tutorialspoint.com/spring/index.htm
    王某某

    概述

    Spring是企业Java最流行的应用程序开发框架。全球数以百万计的开发人员使用Spring Framework创建高性能,易于测试和可重用的代码。

    Spring框架是一个开源的Java平台。它最初由Rod Johnson编写,并于2003年6月首次在Apache 2.0许可下发布。

    Spring框架的核心功能可以用于开发任何Java应用程序,但是在Java EE平台之上还可以扩展构建Web应用程序。Spring框架的目标是通过启用基于POJO的编程模型来使J2EE开发更易于使用,并促进良好的编程实践。

    依赖注入(DI)

    Spring最认常用技术是控制反转的依赖注入(DI)。该控制反转(IOC)是一个笼统的概念,它可以在许多不同的方式来表达。依赖注入仅仅是控制反转的一个具体例子。

    面向切面编程(AOP)

    Spring的关键组件之一是面向切面编程(AOP)框架。跨越应用程序多个点的功能称为横切关注点,这些横切关注点在概念上与应用程序的业务逻辑分离。有各种常见的很好的例子,包括日志记录,声明式事务,安全性,缓存等等。


    框架

    Spring框架提供了大约20个模块,可以根据应用需求使用。

    核心容器

    核心容器由Core,Beans,Context和Expression Language模块组成

    • Core 提供了框架的基本部分,包括IOC和依赖注入特征。
    • Beans 提供的BeanFactory,是工厂模式的一个复杂实现。
    • Context 上下文模块构建在Core和Beans模块提供的基础之上,它是访问定义和配置的任何对象的媒介。ApplicationContext接口是上下文模块的焦点。
    • Expression Language SpEL模块提供了一种强大的表达式语言,用于在运行时查询和操作对象图。

    数据访问/集成

    数据访问/集成层由JDBC,ORM,OXM,JMS和事务模块组成

    • JDBC模块提供了JDBC抽象层,消除了对冗长的JDBC相关编码的需要。
    • ORM模块为流行的对象-关系映射api提供集成层,包括JPA、JDO、Hibernate和iBatis。
    • OXM模块提供了一个抽象层,支持JAXB、Castor、XMLBeans、JiBX和XStream的对象/XML映射实现。
    • Java消息传递服务JMS模块包含用于生成和使用消息的功能。
    • 事务模块支持实现特殊接口和所有pojo的类的编程和声明式事务管理。

    WEB

    Web层由Web,Web-MVC,Web-Socket和Web-Portlet模块组成

    • Web模块提供面向Web的基本集成特性,如多部分文件上传功能,以及使用servlet侦听器和面向Web的应用程序上下文初始化IoC容器。
    • Web-MVC模块包含用于web应用程序的Spring的模型-视图-控制器(MVC)实现。
    • Web-Socket模块支持web应用程序中的客户端和服务器之间的基于websocket的双向通信。
    • Web-Portlet模块提供了将在portlet环境中使用的MVC实现,并镜像了web servlet模块的功能。

    杂项

    重要模块像AOP,Aspects(切面),仪表,消息和测试模块等
    ...
    ...

    Bean定义

    构成应用程序主干和由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。这些bean是用你提供给容器的配置元数据创建的。例如,XML <bean/>定义的形式

    配置一个bean容器需要知道如下信息:

    • 如何创建一个bean
    • Bean的生命周期细节
    • Bean的依赖关系
    属性 说明
    class 该属性是强制性的,指定了用于创建bean的类。
    name 该属性唯一的指定了bean标识符。在基于XML的配置元数据中,使用id (and/or)name属性来指定bean标识符。
    scope 指定了从特定的bean定义创建的对象的范围
    constructor-arg 构造参数,用于注入依赖关系
    properties 属性,用于注入依赖关系
    autowiring mode 自动装配模式,用于注入依赖关系
    lazy-initialization mode 延时加载,告诉IoC容器在第一次请求时创建一个bean实例,而不是在启动时
    initialization method 初始化方法,在bean的所有必要属性设置之后立即调用的回调方面
    destruction method 销毁方法,在bean的容器被销毁时要调用的回调函数

    Spring 配置

    配置Spring一般包括3中方式

    • 基于XML的配置文件
    • 基于注解的配置
    • 基于Java的配置

    基于XML的配置文件示例:

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <!-- A simple bean definition -->
       <bean id = "..." class = "...">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
    
       <!-- A bean definition with lazy init set on -->
       <bean id = "..." class = "..." lazy-init = "true">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
    
       <!-- A bean definition with initialization method -->
       <bean id = "..." class = "..." init-method = "...">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
    
       <!-- A bean definition with destruction method -->
       <bean id = "..." class = "..." destroy-method = "...">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
    
       <!-- more bean definitions go here -->
       
    </beans>
    

    Bean的范围

    定义一个<bean>时,你可以选择为该bean声明一个范围。例如,为了强制Spring在每次需要时产生一个新的bean实例,你应该声明bean的scope属性是prototype。同样,如果你希望Spring在每次需要时都返回相同的bean实例,你应该声明bean的scope属性为singleton

    Spring框架支持以下五个范围,其中三个仅在您使用Web感知的ApplicationContext时才可用。

    范围 说明
    singleton 单实例,每次都使用同一个bean(默认值),对象创建好之后会被缓存,
    prototype 多实例,每次都返回新的实例
    request 在一次HTTP请求中使用相同实例。
    只有在Web感知的Spring ApplicationContext的上下文中才有效。
    session 在一个HTTP会话中使用相同实例。
    只有在Web感知的Spring ApplicationContext的上下文中才有效。
    global-session 在一个全局HTTP会话中使用相同实例。
    只有在Web感知的Spring ApplicationContext的上下文中才有效。

    Bean的生命周期

    初始化回调

    public class ExampleBean implements InitializingBean {
       public void afterPropertiesSet() {
          // do some initialization work
       }
    }
    

    对于基于XML的配置元数据,可以使用init-method属性来指定具有void无参数签名的方法的名称。例如:

    <bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
    
    public class ExampleBean {
       public void init() {
          // do some initialization work
       }
    }
    

    销毁回调

    public class ExampleBean implements DisposableBean {
       public void destroy() {
          // do some destruction work
       }
    }
    

    对于基于XML的配置元数据,可以使用destroy-method属性来指定具有void无参数签名的方法的名称。例如:

    <bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
    
    public class ExampleBean {
       public void destroy() {
          // do some destruction work
       }
    }
    

    默认初始化和销毁方法

    如果你的bean有太多具有相同名称的初始化和/或销毁方法,则不需要在每个单独的bean上声明init-method和destroy-method。这种情况可以使用<beans>元素上的default-init-method和default-destroy-method属性来配置,如下所示:

    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
       default-init-method = "init" 
       default-destroy-method = "destroy">
    
       <bean id = "..." class = "...">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
       
    </beans>
    

    Bean Post Processors

    BeanPostProcessor接口定义了回调方法,你可以实现这些方法来提供您自己的实例化逻辑、依赖解析逻辑等。还可以在Spring容器完成实例化、配置和初始化bean之后,通过插入一个或多个BeanPostProcessor实现来实现一些自定义逻辑。
    可以配置多个BeanPostProcessor接口,并且您可以通过设置order属性来控制这些BeanPostProcessor接口执行的顺序。

    ApplicationContext自动检测由BeanPostProcessor接口实现定义的任何bean,并将这些bean注册为postprocessor,然后容器在创建bean时相应地调用这些bean。

    HelloWorld.java文件的内容:

    package com.tutorialspoint;
    
    public class HelloWorld {
       private String message;
    
       public void setMessage(String message){
          this.message  = message;
       }
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
       public void init(){
          System.out.println("Bean is going through init.");
       }
       public void destroy(){
          System.out.println("Bean will destroy now.");
       }
    }
    

    InitHelloWorld.java文件

    package com.tutorialspoint;
    
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.beans.BeansException;
    
    public class InitHelloWorld implements BeanPostProcessor {
       public Object postProcessBeforeInitialization(Object bean, String beanName) 
          throws BeansException {
          
          System.out.println("BeforeInitialization : " + beanName);
          return bean;  // you can return any other object as well
       }
       public Object postProcessAfterInitialization(Object bean, String beanName) 
          throws BeansException {
          
          System.out.println("AfterInitialization : " + beanName);
          return bean;  // you can return any other object as well
       }
    }
    

    Beans.xml 文件

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"
          init-method = "init" destroy-method = "destroy">
          <property name = "message" value = "Hello World!"/>
       </bean>
    
       <bean class = "com.tutorialspoint.InitHelloWorld" />
    
    </beans>
    

    MainApp.java文件

    package com.tutorialspoint;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
    
          HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
          obj.getMessage();
          context.registerShutdownHook();
       }
    }
    

    执行结果:

    BeforeInitialization : helloWorld
    Bean is going through init.
    AfterInitialization : helloWorld
    Your Message : Hello World!
    Bean will destroy now.
    

    Bean定义继承

    bean定义可以包含许多配置信息,包括构造函数参数、属性值和容器特定的信息,如初始化方法、静态工厂方法名称等。

    子bean定义从父定义继承配置数据。子定义可以覆盖一些值,或者根据需要添加其他值。
    Spring Bean定义继承与Java类继承没有关系,但是继承概念是相同的。可以将父bean定义定义定义为模板,其他子bean可以从父bean继承所需的配置。

    当使用基于xml的配置元数据时,您通过使用父属性指定子bean定义,指定父bean作为该属性的值。

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
          <property name = "message1" value = "Hello World!"/>
          <property name = "message2" value = "Hello Second World!"/>
       </bean>
    
       <bean id =" helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld">
          <property name = "message1" value = "Hello India!"/>
          <property name = "message3" value = "Namaste India!"/>
       </bean>
    </beans>
    

    定义模板

    定义Bean定义模板时,不应指定类属性

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "beanTeamplate" abstract = "true">
          <property name = "message1" value = "Hello World!"/>
          <property name = "message2" value = "Hello Second World!"/>
          <property name = "message3" value = "Namaste India!"/>
       </bean>
    
       <bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">
          <property name = "message1" value = "Hello India!"/>
          <property name = "message3" value = "Namaste India!"/>
       </bean>
       
    </beans>
    

    父bean不能自行实例化,因为它是不完整的,并且它也明确标记为抽象。当定义像这样抽象时,它只能用作纯模板bean定义,作为子定义的父定义。

    依赖注入

    依赖注入主要包括基于构造函数的依赖注入和基于Setter的依赖注入

    基于setter的注入但使用内部bean的配置

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <!-- Definition for textEditor bean using inner bean -->
       <bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
          <property name = "spellChecker">
             <bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"/>
          </property>
       </bean>
    
    </beans>
    

    注入集合

    包括list、set、map、props

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <!-- Definition for javaCollection -->
       <bean id = "javaCollection" class = "com.tutorialspoint.JavaCollection">
          
          <!-- results in a setAddressList(java.util.List) call -->
          <property name = "addressList">
             <list>
                <value>INDIA</value>
                <value>Pakistan</value>
                <value>USA</value>
                <value>USA</value>
             </list>
          </property>
    
          <!-- results in a setAddressSet(java.util.Set) call -->
          <property name = "addressSet">
             <set>
                <value>INDIA</value>
                <value>Pakistan</value>
                <value>USA</value>
                <value>USA</value>
             </set>
          </property>
    
          <!-- results in a setAddressMap(java.util.Map) call -->
          <property name = "addressMap">
             <map>
                <entry key = "1" value = "INDIA"/>
                <entry key = "2" value = "Pakistan"/>
                <entry key = "3" value = "USA"/>
                <entry key = "4" value = "USA"/>
             </map>
          </property>
          
          <!-- results in a setAddressProp(java.util.Properties) call -->
          <property name = "addressProp">
             <props>
                <prop key = "one">INDIA</prop>
                <prop key = "one">INDIA</prop>
                <prop key = "two">Pakistan</prop>
                <prop key = "three">USA</prop>
                <prop key = "four">USA</prop>
             </props>
          </property>
       </bean>
    
    </beans>
    

    将bean引用注入为集合元素中,使引用和值混合在一起

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <!-- Bean Definition to handle references and values -->
       <bean id = "..." class = "...">
    
          <!-- Passing bean reference  for java.util.List -->
          <property name = "addressList">
             <list>
                <ref bean = "address1"/>
                <ref bean = "address2"/>
                <value>Pakistan</value>
             </list>
          </property>
          
          <!-- Passing bean reference  for java.util.Set -->
          <property name = "addressSet">
             <set>
                <ref bean = "address1"/>
                <ref bean = "address2"/>
                <value>Pakistan</value>
             </set>
          </property>
          
          <!-- Passing bean reference  for java.util.Map -->
          <property name = "addressMap">
             <map>
                <entry key = "one" value = "INDIA"/>
                <entry key = "two" value-ref = "address1"/>
                <entry key = "three" value-ref = "address2"/>
             </map>
          </property>
       </bean>
    
    </beans>
    

    要使用上面的bean定义,你需要定义你的setter方法,以便它们也能够处理引用。

    注入空和空字符串值

    空字符串作为值:

    <bean id = "..." class = "exampleBean">
       <property name = "email" value = ""/>
    </bean>
    

    传递一个NULL值

    <bean id = "..." class = "exampleBean">
       <property name = "email"><null/></property>
    </bean>
    

    等同于:exampleBean.setEmail(null)

    相关文章

      网友评论

          本文标题:Spring 介绍

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