Spring

一、Spring简介

           Spring是一个为简化企业级开发而生的开源框架

           Spring是一个IOC(DI)AOP容器框架。

        IOC (Inversion of Control) : 反转控制

        DI (Dependency Injection) : 依赖注入 DI是IOC的一种具体实现

        AOP(Aspect-Oriented Programming) :  面向切面编程   

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

优良特性:①非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API。

                  ②控制反转:指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。

                 ③依赖注入:是指依赖的对象不需要手动调用setXXX方法去设置,而是通过配置赋值。

                  ④面向切面编程:在不修改源代码的基础上进行功能扩展。

                  ⑤容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期。

                   ⑥组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

                    ⑦一站式:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

2、Spring框架分为五大模块:

        (1)Core container:核心容器

                        Bean提供BeanFactory,它是一个工厂模式的复杂实现

                        Core提供了框架的基本组成部分,包括IOC和DI功能

                        Context建立在由核心和bean模块提供的基础上,它是访问定义和配置的任何对象的媒介。ApplicationContext接口是上下文模块的重点

                        SpEL在运行时提供了查询和操作一个对象的强大的Spring

        (2)AOP&Aspects:提供了面向切面编程的实现

        (3)DataAccess/Integration:提供了对数据访问、集成的功能

        (4)Web:提供了面向Web应用程序的集成功能

        (5)Test:提供了对JUnit或TestNG框架的测试功能

3、HelloSpring

        (1) 创建Java工程,并导入jar包

    <dependencies>
        <!--导入spring-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!--导入junit4.12-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

        (2)新建Student【测试类】

        (3)创建Spring核心配置文件【applicationContext.xml或beans.xml】

                        位置:resources目录下

                        将Student类装配到Spring容器中

       (4)创建Spring容器对象【ClassPathXmlApplicationContext】

ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");

         (5) 通过容器获取Student对象  

Student zzq = context.getBean("zzq", Student.class);
        System.out.println("zzq = " + zzq);

4、getBean三种方式

 ①getBean(String id):从spring容器中,通过id获取对象

不足:默认获取对象类型是Object,需要强转,比较繁琐

②getBean(Class clazz):从spring容器中,通过Class获取对象

   不足:当容器中有多个相同Class对象时,会报如下错误:

     expected single matching bean but found 2: ltq,zzq

 ③getBean(String id,Class clazz):从spring容器中,通过id和Class获取对象

    建议使用

5、Spring依赖注入三种方式

 ①set注入<property>

<!--    使用bean标签,装配Student
            id:设置装配对象唯一标识
            class:设置装配对象的全类名【类的全限定名】
-->
    <bean id="ltq" class="com.atguigu.pojo.Student">
<!--        为对象中的属性,注入数值-->
        <property name="id" value="1001"></property>
        <property name="stuName" value="ltq"></property>
    </bean>

②构造器注入<constructor-arg>

<bean id="zzq" class="com.atguigu.pojo.Student">
    <constructor-arg name="id" value="102"></constructor-arg>
    <constructor-arg name="stuName" value="zzq"></constructor-arg>
</bean>

③p名称空间注入 xmlns:p="http://www.springframework.org/schema/p" <P:>

   本质还是set注入

<!-- 引入p名称空间 -- >
xmlns:p="http://www.springframework.org/schema/p"
<bean id="cjy" class="com.atguigu.pojo.Student" p:id="1003" p:stuName="cjy"></bean>

6、Spring中的IOC【DI】

  • Spring中有IOC思想, IOC思想必须基于 IOC容器来完成, 而IOC容器在最底层实质上就是一个对象工厂.

    • Spring实现IOC两种方式

      • BeanFactory【Spring底层实现】

      • ApplicationContext【推荐使用】

  • ApplicationContext结构图

    • ApplicationContext

      • ConfigurableApplicationContext

        • ClassPathXmlApplicationContext【基于类路径下,检索xml文件】

        • FileSystemXmlApplicationContext【基于系统路径(真实路径)下,检索xml文件】

7、Spring中注入数值

 (1)字面量值    可以存储基本数据类型及包装类,String类型的数据

<!--    装配字面量值-->
    <bean id="sls" class="com.atguigu.pojo.Emp">
        <property name="id" value="101"></property>
        <property name="empName" value="sls"></property>
        <property name="age" value="19"></property>
        <property name="salary" value="100"></property>
        <property name="gender" value="男"></property>
<!--        <property name="dept" value="sdfd"></property>-->
    </bean>

 (2)特殊字符    使用CDATA区    < ! [CDATA[ ] ] >

   (3)外部已声明bean    ref

<!--    装配部门-->
    <bean id="jxb" class="com.atguigu.pojo.Dept">
        <property name="deptId" value="1001"></property>
        <property name="deptName" value="教学部门"></property>
        <property name="deptLoc" value="3008"></property>
    </bean>
    <bean id="cxls" class="com.atguigu.pojo.Emp">
        <property name="id" value="103"></property>
        <property name="empName" value="cxls"></property>
        <property name="age" value="20"></property>
        <property name="salary" value="100"></property>
        <property name="gender" value="男"></property>
        <property name="dept" ref="jxb"></property>
    </bean>

 (4)级联属性赋值

<!--    装配部门-->
    <bean id="jxb" class="com.atguigu.pojo.Dept">
        <property name="deptId" value="1001"></property>
        <property name="deptName" value="教学部门"></property>
        <property name="deptLoc" value="3008"></property>
    </bean>
    <bean id="cxls" class="com.atguigu.pojo.Emp">
        <property name="id" value="103"></property>
        <property name="empName" value="cxls"></property>
        <property name="age" value="20"></property>
        <property name="salary" value="100"></property>
        <property name="gender" value="男"></property>
        <property name="dept" ref="jxb"></property>
<!--        级联属性赋值-->
        <property name="dept.deptName" value="财务部门"></property>
    </bean>

如更改级联属性值时,管理bean中属性也同时被更改【级联对象与原对象,是同一个对象】

 (5)内部bean

<!--    内部bean-->
    <bean id="gls" class="com.atguigu.pojo.Emp">
        <property name="id" value="104"></property>
        <property name="empName" value="gls"></property>
        <property name="age" value="18"></property>
        <property name="salary" value="100"></property>
        <property name="gender" value="男"></property>
        <property name="dept">
            <bean id="msbm" class="com.atguigu.pojo.Dept">
                <property name="deptId" value="1001"></property>
                <property name="deptName" value="秘书部门"></property>
                <property name="deptLoc" value="3001"></property>
            </bean>
        </property>
    </bean>

 8、Spring装配第三方bean

  ①导入jar包

<!--导入druid的jar包-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>
<!--导入mysql的jar包-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.37</version>
</dependency>

 ②编写db.properties文件

#key=value
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.initialSize=5
jdbc.maxActive=10

 ③编写applicationContext.xml文件

  • 加载属性文件【db.properties】

  • 装配DruidDataSource数据源

    <?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
           https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!--    加载外部属性文件
                classpath: 基于【当前】类路径加载文件
                classpath*: 基于【所有】类路径加载文件
    -->
        <context:property-placeholder location="classpath:db.properties"/>
    
    <!--    装配DruidDataSource数据源-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    </beans>

 9、Bean的作用域 

 设置bean作用域语法,在bean标签中添加属性:scrop

     ①singleton 单例   在Spring的IOC容器中仅存在一个Bean实例    所有bean的默认作用域

        spring在创建容器对象时,创建bean对象【全局只创建一次容器对象,所以全局只有一个bean对象】

     ②prototype  多例   每次调用getBean方法都会返回一个新的实例   bean标签的scope属性设置

      ③request 请求域  当前请求有效,离开当前请求失效;

       当前请求:地址栏不变即为当前请求,地址栏改变不在当前请求

每次HTTP请求都会创建一个心的Bean实例,该作用域仅适用于WebApplicationContext环境

       ④session 会话域 同一个Session会话共享一个Bean实例,该作用域仅适用于WebApplicationContext环境

10、Bean的生命周期

    1、标准生命周期

 ①通过构造器或工厂方法创建bean实例

 ② 为bean的属性设置值和对其他bean的引用

 ③ 调用bean的初始化方法

 ④  bean可以使用了

 ⑤ 当容器关闭时,调用bean的销毁方法

2、添加后置处理器的生命周期

   ①通过构造器或工厂方法创建bean实例

   ②为bean的属性设置值和对其他bean的引用

      将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法

    ③调用bean的初始化方法

      将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法

    ④bean可以使用了

    ⑤当容器关闭时调用bean的销毁方法

二、Spring中自动装配

 Spring提供的两种装配方式:

   ①手动装配:在bean中添加set注入或者构造注入等方式

  ②自动装配:无需set注入或构造注入,就可以自动装配属性值方式

语法:

     在bean标签中,添加autowire属性,常用属性值有:

               ①byName:通过类中属性名称与ioc容器中id匹配

                 如果匹配成功,则自动装配成功;如果匹配失败,则会将null值装配

                ②byType:通过类中属性类型与ioc容器中的class匹配

                 匹配失败:

                        匹配0个:不会报错,会将null值装配

                        匹配多个:会报错  expected single matching bean but found 2: address,address2

                匹配成功:

                        匹配1个bean时,则匹配成功

注意:自动装配底层使用set注入

        问:实战中建议使用byName或byType呢?

        答:都不建议使用,建议使用注解方式

2、spring中的注解

<1>使用spring注解,简化装配bean配置

(1)@Component   标识一个受Spring IOC容器管理的普通组件

(2)@Repository     标识一个受Spring IOC容器管理的持久化组件

(3)@Service          标识一个受Spring IOC容器管理的业务逻辑层组件

(4)@Controller       标识一个受SpringIOC容器管理的表述层控制组件

注意:使用注解默认会将类名首字母小写作为bean的id

           可以使用value属性为注解,设置bean值【如只书写一个属性值时,value可省略】

<2>使用spring注解,简化装配bean中的属性配置【注入数值】

        @AutoWired    作用:实现自动装配

装配规则:先按照byType方式进行匹配

                如匹配成功【容器中有且仅有一个匹配类型】,则自动装配成功

                如匹配失败 :   ,再按照byName进行匹配,如匹配成功则正常使用,如匹配失败,则会按照byType方式提示错误信息

                  匹配0个:required=true【默认值】,会报错

expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

                                    required=false  不会报错,会将null值装配

                  匹配多个:会报错:expected single matching bean but found 2:address,address2

<3>@Autowired中的required属性作用:设置装配属性**是否必须**自动装配

        required=true:必须为指定属性自动装配

        required=false:不必须为指定属性自动装配

<4>  默认@Autowired注解书写在字段中 ,底层反射方式注入数值

        @AutoWired注解书写在setXXX() 方法中,底层使用set方式 注入

        @AutoWired注解书写在构造方法中,底层使用构造器方式注入

<5> @Qualifier注解:

        将ioc容器中bean的id 自动装配到指定类的属性中

        一般与@Autowired注解配合使用

<6>@Value注解,自动装配字面量数值

3、Spring组件扫描

 原因:需要使用注解,就必须开启组件扫描

<1>方式一:默认开启组件扫描【扫描当前包及其子包】

 <context:component-scan base-package="com.atguigu"></context:component-scan>

<2>方式二:排除扫描

 <context:component-scan base-package="com.atguigu">
        <!--        设置排除组件指定注解全限定名【全类名】-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <!--        设置排除组件指定类全限定名【全类名】-->
<!--        <context:exclude-filter type="assignable" expression="com.atguigu.service.impl.StudentServiceImpl"/>-->
    </context:component-scan>

<3>方式三:包含扫描   

        使用包含扫描需要将默认组件扫描关闭【use-default-fifters="false"】

    <context:component-scan base-package="com.atguigu" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<!--        <context:include-filter type="assignable" expression="com.atguigu.dao.impl.StudentDaoImpl"/>-->
<!--        <context:include-filter type="assignable" expression="com.atguigu.dao.impl.StudentMapperImpl"/>-->
    </context:component-scan>

4、完全注解开发

步骤:

①创建配置类

②为配置添加相应的注解

  @Configuration:设置当前类为配置类,用来代替xml配置文件

  @ComponentScan:为配置类,开启组件扫描

③创建AnnotationConfigApplicationContext容器对象,并使用

package com.atguigu.springutil;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Creates with IntelliJ IDEA.
 * Author: 李龙
 * Date: 2021/10/12 16:11
 * Description: TODO
 * Since  version-1.0
 */
@ComponentScan(basePackages = "com.atguigu")
@Configuration
public class SpringConfig {
}
import com.atguigu.bean.Student;
import com.atguigu.service.StudentService;
import com.atguigu.service.impl.StudentServiceImpl;
import com.atguigu.springutil.SpringConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Creates with IntelliJ IDEA.
 * Author: 李龙
 * Date: 2021/10/12 16:12
 * Description: TODO
 * Since  version-1.0
 */
public class Test05NoXml {

    @Test
    public void test(){

        //创建容器对象【配置类】
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        //从容器中获取bean对象
        StudentServiceImpl studentService = context.getBean("studentService", StudentServiceImpl.class);
        //StudentServiceImpl studentService  = context.getBean("studentService", StudentService.class);//也可以,底层反射原理
        //调用bean对象中相应方法
        studentService.addStudent(new Student());
    }
}

5、Spring整合Junit4

步骤:

①导入spring-test:5.3.1.jar包

<!--spring集成junit4-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.1</version>
        </dependency>

②添加注解

   @ContextConfiguration(locations="classpath:   ")

   @RunWith(SpringJUnit4ClassRunner.class)

③装配测试类,并使用

import com.atguigu.bean.Student;
import com.atguigu.service.StudentService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Creates with IntelliJ IDEA.
 * Author: 李龙
 * Date: 2021/10/12 16:20
 * Description: TODO
 * Since  version-1.0
 */
@ContextConfiguration(locations = "classpath:applicationContext_annotation.xml")
// @ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class Test06SpringJunit {
    

    @Autowired
    private StudentService studentService;

    /**
     * Spring整合Junit4
     */
    @Test
    public void testSpringUserService(){

        System.out.println("studentService = " + studentService);

        studentService.addStudent(new Student());
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值