Spring学习(总结、笔记)

零、自己的总结

0.1 配置文件的约束

不使用注解时

<?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">
</beans>

使用注解时

<?xml version="1.0" encoding="UTF-8"?>
<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
        http://www.springframework.org/schema/context/spring-context.xsd">

0.2 XML的配置

bean标签

作用: 用于配置对象让spring来创建的。 默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。 

代码

 <bean id="accountService"  class="com.itheima.service.impl.AccountServiceImpl" scope=""  init-method="" destroy-method="">
	<property name=""  value="" | ref=""></property>
</bean>

理解

属性:

  1. id:给对象在容器中提供一个唯一标识。用于获取对象。
  2. class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造数。
  3. scope:指定对象的作用范围。
    1. singleton :默认值,单例的.
    2. prototype :多例的。
    3. request :WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中
    4. session :WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中
    5. global session :WEB项目中,应用在Portlet环境.如果没有Portlet环境那globalSession相当于session.
  4. init-method:指定类中的初始化方法名称。
  5. destroy-method:指定类中销毁方法名称。

0.3 一些概念

  1. 有下面三个重要的方法把配置元数据提供给 Spring 容器
    基于 XML 的配置文件
    基于注解的配置
    基于 Java 的配置

  2. applicationContext & BeanFactory区别
    BeanFactory接口
    (1) spring的原始接口,针对原始接口的实现类功能较为单一
    (2)BeanFactory接口实现类的容器,特点是每次在获得对象时才会创建对象

    ApplicationContext接口
    (1)每次容器启动时就会创建容器中配置的所有对象
    (2)提供了更多功能
    (3)从类路径下加载配置文件: ClassPathXmlApplicationContext
    硬盘的绝对路径下加载配置文件:FileSystemXmlApplication

控制反转

控制反转IOC——Inversion of Control,指的是将对象的创建权交给Spring去实现IOC思想需要DI做支持。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。

依赖注入

依赖注入DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设值,而是通过配置赋值。
spring这个容器中,替你管理着一系列的类,前提是你需要将这些类交给spring容器进行管理,然后在你需要的时候,不是自己去定义,而是直接向spring容器索取,当spring容器知道你的需求之后,就会去它所管理的组件中进行查找,然后直接给你所需要的组件.

容器

容器:Spring可以看作是一个装有对象的map集合,因为它包含并且管理应用对象的生命周期

耦合概念

  1. 什么是程序的耦合
    模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差。
    在软件工程中,耦合指的就是就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。
    内聚与耦合:内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽和局部化概念的自然扩展。它描述的是模块内的功能联系。
    在进行软件设计时,应力争做到高内聚低耦合

  2. 怎么降低耦合?
    解耦:降低程序间的依赖关系,实际开发中,应该做到:编译期不依赖运行时才依赖
    解耦的思路:工厂模式解耦
    第一步:使用反射来创建对象,而避免使用new关键字。
    第二步:通过读取配置文件来获取要创建的对象全限定类名

  3. 工厂模式解耦
    创建一个Bean对象的工厂。
    第一个:需要一个配置文件来配置我们需要创建对象的属性,配置的内容:唯一标识 = 全限定类名(key=value)
    第二个:通过读取配置文件中配置的内容,反射创建对象,我的配置文件可以是xml也可以是properties

一、Spring概述

核心是什么?

  1. Spring的核心是控制反转(IoC)和面向切面(AOP)
    控制反转:把创建对象的事交给spring框架来做,spring创建的对象存在一个类似于map集合的IoC容器中。

Spring是什么?

**轻量级开源框架**,使用Spring开发可以将Bean对象,Dao组件对象,Service组件**对象等交给Spring容器来管理**,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,**有效的降低代码的耦合度**,极大的**方便项目的后期维护**、**升级和扩展**。

Spring的优势

  1. 方便解耦,简化开发(高内聚低耦合)
    Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护交给Spring管理spring工厂是用于生成bean
  2. AOP编程的支持
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  3. 声明式事务的支持
    只需要通过配置就可以完成对事务的管理,而无需手动编程,提高开发效率和质量。
  4. 方便程序的测试
    Spring对Junit4支持,可以通过注解方便的测试Spring程序
  5. 方便集成各种优秀框架
    Spring不排斥各种优秀的开源框架,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
  6. 降低JavaEE API的使用难度
    Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
  7. Java源码是经典学习范例
    Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是Java技术的最佳实践的范例。

二、控制反转(IOC)

2.1 IOC入门案例

2.1.1 pom.xml文件

导入jar包
代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.Ljj</groupId>
    <artifactId>day01_Spring_IOC</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    </dependencies>
</project>

2.1.2 配置文件applicationContext.xml

applicationContext.xml放在resources文件下面。
代码:

<?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">
    <!-- 配置service 
        bean标签:配置需要创建的对象,并且存入IoC容器中
            id :相当于命名,用于之后从spring容器获得实例时使用的
            class :需要创建实例的全限定类名
    -->
    <bean id="userService" class="com.ljj.Service.UserServiceImpl"></bean>
</beans>

2.1.3 测试

代码:

   @Test
    public void testIOC(){
        //1.获得容器
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        //2.获得对象。不需要自己new,从spring容器获得
        //括号中的userService指的就是配置文件中的id属性
        UserService userService = (UserService) applicationContext.getBean("userService");

2.2 DI入门案例

2.2.1 UserDao和UserDaoImpl

UserDao:

public interface UserDao {
    public void save();
}

UserDaoImpl:


public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("di add user");
    }
}

2.2.2 UserService接口

public interface UserService {
    public abstract void addUser();
}
public class UserServiceImpl implements UserService {
    // 之前:接口 = new 实现类
    // 现在:接口 + setter
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void addUser(){
        this.userDao.save();
    }
}

2.2.3 配置文件bean.xml

<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">
    <!-- 
    模拟spring执行过程
        创建service实例:UserService userService = new UserServiceImpl(); IoC  <bean>
        创建dao实例:UserDao userDao = new UserDaoImpl();         		IoC <bean>
        将dao设置给service:userService.setUserDao(userDao);    		 	DI   <property>

     <property> 用于进行属性注入
         name: bean的属性名,通过setter方法获得
             setBookDao ##> BookDao  ##> bookDao
         ref :另一个bean的id值的引用
     -->
     
    <!-- 创建service -->
    <bean id="userService" class="com.ljj.Service.UserServiceImpl">
        <property name="userDao" ref="UserDao"></property>
    </bean>
    
    <!-- 创建dao实例 -->
    <bean id="userDao" class="com.ljj.Dao.UserDaoImpl"></bean>
</beans>

2.2.4 测试

    @Test
    public void demo01(){
        //1.获得容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        //2.创建对象
        UserService userService = (UserService) applicationContext.getBean("userService")
        //3.调用方法
        userService.addUser();
    }

2.3 Spring BeanFactory 容器

  1. 它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。

  2. 在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。

  3. 第一步:利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。

  4. 第二步:利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法。

2.4 Spring ApplicationContext 容器

  1. Application Context 是 BeanFactory 的子接口,也被称为 Spring 上下文。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。

  2. 最常被使用的 ApplicationContext 接口实现类

    1. FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。需要提供给构造器 XML 文件的完整路径。它可以加载磁盘任意路径下的配置文件(必须有访问权限),
    2. ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。它可以加载类路径下的配置文件,要求配置文件必须在类路径下。
    3. WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
    4. AnnotationConfigApplicationContext:它是用于读取注解创建容器的。
  3. 主程序代码

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new FileSystemXmlApplicationContext
            ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
   }
}

需要注意以下两点:

第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext API 去生成工厂 bean。FileSystemXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。

第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。

2.5 Spring Bean 定义

配置如下:

 <bean id="accountService"  class="com.itheima.service.impl.AccountServiceImpl" scope=""  init-method="" destroy-method="">
	<property name=""  value="" | ref=""></property>
</bean>
  1. bean的属性
    id:指的是创建出的bean对象的名称
    class:这个属性是强制性的,并且指定用来创建 bean 的 bean 类。
    name:这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。
    scope:这个属性指定由特定的 bean 定义创建的对象的作用域
    最常用的是singleton(单例)、prototype(多例)。
    constructor-arg构造函数注入依赖关系。
    properties:它是用来注入依赖关系的

  2. 三种配置方式:

  3. 第一种方式:使用默认构造函数创建。
    在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

<bean id="accountService" class="com.ljj.service.impl.AccountServiceImpl"></bean>
  1. 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"	></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
  1. 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
 <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>

2.6 Spring Bean 作用域

  1. 作用域指的是bean标签的scope属性:
    作用:用于指定bean的作用范围
    取值: 常用的就是singleton的和prototype的。
    细节:对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

scope属性

  1. singleton单例的(默认值)。就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
    <!-- collaborators and configuration for this bean go here -->
</bean>
  1. prototype多例的。它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个bean对象,每次获取到的对象都不是同一个对象。
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
   <!-- collaborators and configuration for this bean go here -->
</bean>
  1. request:作用于web应用的请求范围
  2. session:作用于web应用的会话范围
  3. global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session。

2.7 Spring Bean 生命周期

  1. 当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁
  2. 初始化
    init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。在基于 XML 的配置元数据的情况下,你可以使用 init-method 属性来指定带有 void 无参数方法的名称。
<bean id="exampleBean" class="examples.ExampleBean" init-method="init"/>
  1. 销毁
    destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。在基于 XML 的配置元数据的情况下,你可以使用 destroy-method 属性来指定带有 void 无参数方法的名称。
<bean id="exampleBean" class="examples.ExampleBean" destroy-method="destroy"/>

单例和多例的生命周期

  1. 单例对象:scope=“singleton”
    出生:当容器创建时对象出生
    活着:只要容器还在,对象一直活着
    死亡:容器销毁,对象消亡
    总结:单例对象的生命周期和容器相同

  2. 多例对象:scope=“prototype”
    出生:当我们使用对象时spring框架为我们创建
    活着:对象只要是在使用过程中就一直活着。
    死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

三、依赖注入DI

  1. 依赖注入用来装配Bean

  2. 依赖注入方式三种装配方式:
    基于xml装配:构造方法setter方法
    基于注解装配

  3. 依赖注入:Dependency Injection(DI),通过依赖注入的方式来管理Bean之间的依赖关系。
    IOC的作用:降低程序间的耦合(依赖关系)
    依赖关系的管理:以后都交给spring来维护,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明,依赖关系的维护,就称之为依赖注入
    能注入的数据:有三类
    1.基本类型和String
    2.其他bean类型(在配置文件中或者注解配置过的bean)
    3.复杂类型/集合类型

    注入的方式:有三种
    第一种:使用构造函数提供
    第二种:使用set方法提供
    第三种:使用注解提供(明天的内容)

3.1 构造函数注入

  1. 容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。

  2. 使用的标签:constructor-arg
    标签出现的位置:bean标签的内部
    标签中的属性:

    1. type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
    2. index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
    3. name:用于指定给构造函数中指定名称的参数赋值(常用的 )。
      以上三个用于指定给构造函数中哪个参数赋值
    4. value:用于提供基本类型和String类型的数据
    5. ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
  3. 构造函数注入优劣势

    1. 优势:
      在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    2. 弊端:
      改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
  4. 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">
   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <constructor-arg ref="spellChecker"/>
   </bean>
   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>

3.2 设值函数的依赖注入

  1. 当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了。

  2. set方法注入(更常用的方式)
    涉及的标签:property
    出现的位置:bean标签的内部
    标签的属性:

    1. name:用于指定注入时所调用的set方法名称
    2. value:用于提供基本类型和String类型的数据
    3. ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
  3. 优劣势

    1. 优势:
      创建对象时没有明确的限制,可以直接使用默认构造函数
    2. 弊端:
      如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
  4. 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">
   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <property name="spellChecker" ref="spellChecker"/>
   </bean>
   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>
</beans>

3.3 复杂类型的注入/集合类型的注入

涉及的标签:property
出现的位置:bean标签的内部

  1. 用于给List结构集合注入的标签:
    list array set
  2. 用于个Map结构集合注入的标签:
    map props
    结构相同,标签可以互换

下面是配置所有类型的集合的配置文件 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">
   <!-- 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="two">Pakistan</prop>
            <prop key="three">USA</prop>
            <prop key="four">USA</prop>
         </props>
      </property>
   </bean>
</beans>

3.4 基于注解依赖注入

  1. 注解:就是一个类,使用@注解名称

  2. 开发中:使用注解 取代 xml配置文件。

    1. @Component 取代< bean class= " " >
      @Component( “id” ) 取代 < bean id = " " class = " ">
    2. web开发,提供3个@Component注解衍生注解(功能一样)取代
      @Repository :dao层
      @Service:service层
      @Controller:web层
  3. 依赖注入,给私有字段设值,也可以给setter方法设值
    普通值:@Value(" ")
    引用值:
    方式1:按照【类型】注入
    @Autowired
    方式2:按照【名称】注入1
    @Autowired
    @Qualifier(“名称”)
    方式3:按照【名称】注入2
    @Resource(“名称”)

  4. 生命周期
    初始化:@PostConstruct
    销毁:@PreDestroy

  5. 作用域
    @Scope(“prototype”) 多例
    @Scope(“singleton”) 单例

三、Spring 依赖注入

四、注解方式

曾经XML的配置:

 <bean id="accountService"  class="com.itheima.service.impl.AccountServiceImpl" scope=""  init-method="" destroy-method="">
	<property name=""  value="" | ref=""></property>
</bean>

分成了四个方面:
1.用于创建对象的
2.用于注入数据的
3.用于改变作用范围的
4.和生命周期相关

4.1 用于创建对象

  1. 用于创建对象时他们的功能相当于在XML配置文件中编写一个< bean >标签。注解使用位置:要创建对象的上面。

  2. 使用的注解通常有4个:
    Controller:一般用在表现层
    Service:一般用在业务层
    Repository:一般用在持久层
    Component:不属于上面三层时候使用
    四个注解作用和属性是完全一样的,上面三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
    属性:value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。只有一个value属性时候可以省略value。

4.2 用于注入数据

  1. 他们的作用就和在xml配置文件中的bean标签中写一个< property >标签的作用是一样的。出现位置:可以是变量上,也可以是方法上。

常用的注解:

  1. Autowired
    作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。如果Ioc容器中有多个类型匹配时:使用Qualifier标签搭配。

    1. 属性中的 @Autowired
      配置在成员变量上面。你可以在属性中使用 @Autowired 注释来除去 setter 方法。当时使用 为自动连接属性传递的时候,Spring 会将这些传递过来的值或者引用自动分配给那些属性。
    2. 构造函数中的 @Autowired
      一个构造函数 @Autowired 说明当创建 bean 时,即使在 XML 文件中没有使用 元素配置 bean ,构造函数也会被自动连接。
  2. Qualifier
    作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用要配合Autowired使用。当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱

4.3 用于改变作用范围

  1. 他们的作用就和在bean标签中使用scope属性实现的功能是一样的

  2. 使用的注解:
    Scope
    作用:用于指定bean的作用范围
    value属性:指定范围的取值。常用取值:singleton(单例)、prototype(多例)。

4.4 生命周期相关

  1. 他们的作用就和在bean标签中使用init-methoddestroy-methode是一样的。

  2. 使用的注解:
    PreDestroy
    作用:用于指定销毁方法
    PostConstruct
    作用:用于指定初始化方法

4.5 纯注解方式

  1. 使用纯注解方式,也就是把bean.xml删除了。需要创建一个配置类,它的作用和bean.xml是一样。

代码

主配置类中代码:

//Configuration注解指定当前类是一个配置类。
@Configuration
//用于通过ComponentScan注解指定spring在创建容器时要扫描的包
@ComponentScan("com.itheima")
//Import用于导入其他的配置类(子配置类)。例如连接数据库的类。
@Import(JdbcConfig.class)
//PropertySource用于指定properties文件的位置
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {
}

子配置类中代码:(连接数据库用)‘’

public class JdbcConfig {
	//使用value注解注入数据
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 用于创建一个QueryRunner对象
     * @param dataSource
     * @return
     */
     //Bean用于把当前方法的返回值作为bean对象存入spring的ioc容器中
    @Bean(name="runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }
     /**
     * 创建数据源对象
     * @return
     */
    @Bean(name="ds")
    public DataSource createDataSource(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

注解说明

  1. 注解说明
    1.Configuration
    作用:指定当前类是一个配置类。
    细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。

    2.ComponentScan
    作用:用于通过注解指定spring在创建容器时要扫描的包
    属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。我们使用此注解就等同于在xml中配置了:<context:component-scan base-package="com.itheima"> </context:component-scan>
    3.Bean
    作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
    属性:name:用于指定bean的id。当不写时,默认值是当前方法的名称
    细节:当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。查找的方式和Autowired注解的作用是一样的。
    4.Import
    作用:用于导入其他的配置类(子配置类)。例如连接数据库的类。
    属性:value:用于指定其他配置类的字节码。
    细节:当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类。
    5.PropertySource
    作用:用于指定properties文件的位置
    属性:value:指定文件的名称和路径,其中关键字:classpath,表示文件是在类路径下。

五、整合Junit单元测试

分析

  1. 分析
    1、应用程序的入口main方法
    2、junit单元测试中,没有main方法也能执行,junit集成了一个main方法,该方法就会判断当前测试类中哪些方法有 @Test注解,junit就让有Test注解的方法执行。
    3、junit不会管我们是否采用spring框架,在执行测试方法时,junit根本不知道我们是不是使用了spring框架,所以也就不会为我们读取配置文件/配置类创建spring核心容器
    4、由以上三点可知
    当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入。

  2. 解决方法:Spring整合junit的配置
    1、导入spring整合junit的jar(坐标):spring-test
    2、使用Junit提供的一个注解 @Runwith把原有的main方法替换了,替换成spring提供的
    3、使用**@ContextConfiguration**注解告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置。
    *@ContextConfiguration注解中的两个属性:
    1.locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
    2.classes:指定注解类所在地位置

注意:当我们使用spring 5以上版本的时候,要求junit的jar必须是4.12及以上。

代码

     @RunWith(SpringJUnit4ClassRunner.class)//帮我们创建容器
     @ContextConfiguration("classpath:applicationContext.xml")//指定创建容器时使用哪个配置文件
     public class AnnotationTest(){
     //将名为student的对象注入到student中
     @Resource(name="student")
     private Student student;
     }
     @Test
     //下面是一些单元测试的方法    
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页