Spring学习笔记——概述~bean

北城余情 提交于 2020-08-05 08:55:14

Spring学习笔记——概述~bean

参考:【狂神说Java】Spring5最新完整教程IDEA版通俗易懂
尚硅谷-Spring5框架2020最新版教程

1. Spring概述

  • 百度百科
    • Spring框架是一个开源的J2EE应用程序框架,是针对bean的生命周期进行管理的轻量级容器。
    • Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。
    • Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。
    • Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
  • 官网https://spring.io/
  • 英文文档https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/
  • API文档https://docs.spring.io/spring/docs/5.2.7.RELEASE/javadoc-api/
  • 组成
    • Spring Core:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
    • Spring Context:Spring 上下文是一个配置文件,向 Spring框架提供上下文信息。Spring 上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化、校验和调度功能。
    • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
    • Spring DAO:JDBCDAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
    • Spring ORM:负责框架中对象关系映射,提供相关ORM 接入框架的关系对象管理工具 。Spring 框架插入了若干个ORM框架,从而提供了 ORM 的对象关系工具,其中包括JDO、Hibernate和iBatisSQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
    • Spring Web :Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
    • Spring MVC :MVC框架是一个全功能的构建 Web应用程序的 MVC 实现。通过策略接口,MVC框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。模型由javabean构成,存放于Map;视图是一个接口,负责显示模型;控制器表示逻辑代码,是Controller的实现。Spring框架的功能可以用在任何J2EE服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同J2EE 环境、独立应用程序、测试环境之间重用。
  • ss

2. 第一个程序HelloSpring

  1. 新建maven项目

  2. 引入pom依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.7.RELEASE</version>
    </dependency>
    
  3. 编写实体类

    public class Student {
        String name;
        //getter-setter,全参无参构造
    }
    
  4. 编写配置文件

    <?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.xsd">
        <!-- 使用bean元素定义一个由容器创建的对象-->
    	<!-- class属性指定用于创建bean的全类名-->
    	<!-- id属性指定用于引用bean实例的名称-->
        <bean id="student" class="com.naclo.pojo.Student">
            <!-- 使用property子元素为bean的属性赋值-->
            <property name="name" value="NaClO"/>
        </bean>
    </beans>
    
  5. 编写测试类

    @Test
    public void test() {
        //创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //根据配置的id获取bean对象实例
        Student student = (Student)context.getBean("student");
        System.out.println("student = " + student);
    }
    

    输出:student = Student(name=NaClO)

3. bean

1. bean标签

  • 用于创建对象

    <bean id="" class="" scope="">
    
    </bean>
    
    • id:对象名;
    • class:类的全类名;
    • scope:对象的作用域
      • singleton:单例对象;
      • prototype:多例对象;
      • request:创建对象并放入request中;
      • session:创建对象并放入session中;

2. 实例化Bean的方式

  1. 使用默认无参构造函数

    • 默认情况下调用无参构造函数创建对象,如果没有无参构造函数,会创建失败

      <bean id="initStudent" class="com.naclo.pojo.Student">
      </bean>
      
  2. 使用静态工厂的方法创建对象

    • 模拟一个静态工厂

      public class StaticFactory {
          public static Student createStudent() {
              return new Student();
          }
      }
      
    • 使用静态工厂创建对象

      <bean id="staticStudent" class="com.naclo.factory.StaticFactory" 
            factory-method="createStudent">
      </bean>
      
      • class:静态工厂的全类名;
      • factory-method:创建对象的静态方法;
  3. 使用实例工厂的方法创建对象

    • 模拟一个实例工厂

      public class InstanceFactory {
          public Student createStudent() {
              return new Student();
          }
      }
      
    • 使用实例工厂创建对象

      <!-- 先创建工厂实例,再调用方法创建对象 -->
      <bean id="instanceFactory" class="com.naclo.factory.InstanceFactory"></bean>
      <bean id="instanceStudent" factory-bean="instanceFactory" 
            factory-method="createStudent">
      </bean>
      
      • factory-bean:实例工厂的id;
      • factory-method:创建对象的方法;

3. 依赖注入DI

无参构造函数,使用set注入

<bean id="student" class="com.naclo.pojo.Student">
    <property name="name" value="NaClO"/>
</bean>
  • name:属性名;
  • value:给属性赋值,值为基本数据类型;
  • ref:给属性赋值,值为其他bean类型;

有参构造函数,使用构造函数注入

<bean id="student" class="com.naclo.pojo.Student">
    <constructor-arg value="NaClO"/>
</bean>
  • 使用constructor-arg指定参数赋值

    • 自动匹配合适的参数位置

      <constructor-arg value="NaClO"/>
      
    • 通过参数名字指定参数位置

      <constructor-arg name="name" value="NaClO"/>
      
    • 通过索引值指定参数位置

      <constructor-arg index="0" value="NaClO"/>
      
    • 通过类型指定参数位置

      <constructor-arg type="java.lang.String" value="NaClO"/>
      

集合属性注入

  • 当参数变量是集合类型的时候注入。

    • 创建一个实体对象

      public class CollectionTest {
          String[] array;
          List<String> list;
          Set<String> set;
          Map<String, String> map;
          Properties properties;
          //getter-setter,全参无参构造
      }
      
    • 实例化对象

      <bean id="collectionTest" class="com.naclo.pojo.CollectionTest">
          <!-- array -->
          <property name="array">
              <array>
                  <value>A</value>
                  <value>B</value>
                  <value>C</value>
              </array>
          </property>
          <!-- list -->
          <property name="list">
              <list>
                  <value>A</value>
                  <value>B</value>
                  <value>C</value>
              </list>
          </property>
          <!-- set -->
          <property name="set">
              <set>
                  <value>A</value>
                  <value>B</value>
                  <value>C</value>
              </set>
          </property>
          <!-- map -->
          <property name="map">
              <map>
                  <entry key="A" value="A" />
                  <entry key="b" value="b" />
                  <entry key="C" value="C" />
              </map>
          </property>
          <!-- properties -->
          <property name="properties">
              <props>
                  <prop key="A">A</prop>
                  <prop key="B">B</prop>
                  <prop key="C">C</prop>
              </props>
          </property>
      </bean>
      

其他注入方式

  • P命名空间注入

    • 格式:p:属性名="属性值"p:属性名-ref="id"

    • 导入约束

      xmlns:p="http://www.springframework.org/schema/p"
      
    • 例子

      <bean id="student" class="com.naclo.pojo.Student" p:name="NaClO"/>
      
  • c 命名空间注入

    • 格式:c:属性名="属性值"c:属性名-ref="id"

    • 导入约束

      xmlns:c="http://www.springframework.org/schema/c"
      
    • 例子

      <bean id="student" class="com.naclo.pojo.Student" c:name="NaClO"/>
      

4. 引入外部配置文件

  1. 编写外部配置文件xxx…properties放在resources目录下

    name=NaClO
    
  2. 引入context 名称空间

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                https://www.springframework.org/schema/context/spring-context.xsd">
    
  3. 指定配置文件位置

    <context:property-placeholder location="classpath:student.properties"/>
    
  4. 读取配置文件

    <bean id="student" class="com.naclo.pojo.Student">
        <property name="name" value="${name}"/>
    </bean>
    

5. 自动装配

  1. 概念

    • 手动装配
      • 以value 或ref 的方式明确指定属性值
    • 自动装配
      • 根据指定的装配规则,不需要明确指定,Spring 自动将匹配的属性值注入
        bean 中。
  2. 装配方式

    1. 根据类型自动装配:将类型匹配的bean 作为属性注入到另一个bean 中。若IOC 容器中
      有多个与目标bean 类型一致的bean,Spring 将无法判定哪个bean 最合适该属性,所
      以不能执行自动装配

    2. 根据名称自动装配:必须将目标bean 的名称和属性名设置的完全相同
  3. 测试

    1. 创建两个实体类A和B

      public class A {
      }
      
      public class B {
      }
      
    2. 创建实体类C,属性为A,B

      public class C {
          A a;
          B b;
      }
      
    3. 配置A和B

      <bean id="a" class="com.naclo.pojo.A"/>
      <bean id="b" class="com.naclo.pojo.B"/>
      
    4. 根据类型自动装配

      <bean id="c" class="com.naclo.pojo.C" autowire="byType"/>
      
    5. 根据名称自动装配

      <bean id="c" class="com.naclo.pojo.C" autowire="byName"/>
      

6. 使用注解注入

1. 开启注解

  1. 在配置文件中引入context文件头

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                https://www.springframework.org/schema/context/spring-context.xsd">
    
  2. 开启属性注解支持

    <context:annotation-config/>
    

2. @Autowired

  • 按类型自动装配,不支持按id匹配;

    public class C {
        @Autowired
        A a;
        @Autowired
        B b;
    }
    
  • @Autowired(required=false)

    • false:对象可以为null;
    • true:对象不能为null;

3. @Qualifier

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配;

  • @Qualifier不能单独使用;

    public class C {
        @Autowired
        @Qualifier(value = "a")
        A a;
        @Autowired
        @Qualifier(value = "b")
        B b;
    }
    

4. @Resource

  • 先进行byName查找,再进行byType查找;

  • 如果允许对象为null,设置required = false,默认为true

    public class C {
        @Resource(name = "a")
        A a;
        @Resource
        B b;
    }
    

7. 其他

1. 别名alias

  • 为bean设置别名,可以使用别名获取bean

    <alias name="student" alias="NaClO"/>
    

2. 导入

  • 可以导入外部的bean,实现分文件编写,方便团队合作

    <import resource="classpath:beans.xml"/>
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!