JavaWeb框架 - Spring01

Spring框架的概述和入门案例

  1. spring框架的概述:【了解即可】
    • spring是什么:spring是分层的JavaSE/EE应用的full-stack的轻量级开源框架,以IOC(控制反转)和AOP(面向切面编程),提供了表现层SpringMVC和持久层的springJDBC,及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
    • spring的优势:
      • 方便解耦,简化开发:通过的spring中的IoC核心容器,将对象之间的依赖关系交由Spring进行控制,避免硬编码造成的过度耦合,用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
      • AOP编程的支持:通过spring中的aop功能,方便的进行面向切面编程,使许多难以适用传统的oop思想实现的功能能够轻松的实现。
      • 声明式事务的支持:可以从单调的事务管理的代码中解脱出来,通过声明式的方式对事务进行管理,提高开发的效率和质量。
      • 方便集成其他的第三方框架:spring中降低了集成其他框架的难度,提供了对其他框架的支持。
      • 降低了对JavaEEapi的使用难度:对常用的JavaEEAPI进行了简单的封装,如javaMail,JDBCTemplate,使用这些API的难度大大的降低。
    • Spring框架的体系结构:
      Spring框架的体系结构
  2. Spring中的控制反转:
    • 什么是程序的耦合和解耦:
      • 程序之间的耦合性: 在软件工程中,程序之间的耦合就是对象之间的依赖性,对象之间耦合性越高,维护的成本就越高。因此,对象之间的设计应当使类和构件耦合之间最小(高内聚 和 低耦合)
      • 解耦的两种思路:
        • 创建对象的时候尽量不要使用new关键字,而是使用反射,通过读取配置文件的方式来获取要创建对象的全限定类名。例如:在使用jdbc的时候注册驱动使用的是反射的形式,而不是用DriverManager的register方法。从而降低程序之间的耦合性。
        • 使用工厂模式来进行解耦:当服务器启动应用加载的时候,让一个类中的方法通过读取配置文件,将对象都创建出来并且存起来,在以后使用的时候,直接拿过来使用,而读取配置文件来创建对象的类就是工厂。如SqlSessionFactory 就是一个工厂类。
    • Spring中的控制反转IoC:
      • 控制反转IoC:在使用工厂类的时候创建多个对象,需要将对象存起来,且能将对象查询出来,这样就需要一个Map,spring中就是IOC核心容器,而使用new的方式来创建对象,是主动的方式;使用工厂模式获取对象时,跟工厂要,由工厂为我们查找或者创建对象。是被动的方式,这样就将对象创建的权利交给了框架中的核心容器,这就是控制反转。【注意】:控制反转不是面向对象的术语,而是框架的重要特征。
      • 控制反转的作用:降低程序之间的耦合性,注意的是是降低耦合 不是完全的消除程序之间的耦合性是不能完全的消除的,从而在实际的开发过程中实现:在编译期不依赖,而是在程序的运行期依赖。
      • 使用Spring中的IoC解决程序之间的耦合:
        • 准备工作:创建一个Maven工程,编写三层架构的接口和实现类。

        • 进行Maven pom.xml文件的配置:

          <?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>cn.itheima</groupId>
              <artifactId>springIoc</artifactId>
              <version>1.0-SNAPSHOT</version>
          
              <dependencies>
              	<!-- 引入 spring框架的坐标 使用的是5.0.2版本-->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-context</artifactId>
                      <version>5.0.2.RELEASE</version>
                  </dependency>
              </dependencies>
          
          </project>
            
          
        • 进行Bean对象的管理:在Maven工程中的resources目录下创建一个Bean.xml文件,将对象的创建交给Spring框架来处理,进行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.xsd">
              <!--把对象的创建交给spring来管理-->
              <bean id="accountService" class="com.itheima.service.impl.IAccountServiceImpl"></bean>
              <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
          </beans>
          
        • 使用容器来创建对象的getBean方法来获取对象,执行相应的方法。常用的容器有三种: ClassPathXmlApplicationContext,FileSystemXmlApplicationContext,AnnotationConfigApplicationContext都实现了ApplicationContext接口。

          • xml配置:
            • ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件,推荐使用的方式
            • FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件能在磁盘中的任意位置(绝对路径)
          • 注解配置:
            • AnnotationConfigApplicationContext: 读取注解创建容器
    • Spring中基于xml配置实现IoC的细节:
      • Spring中的工厂类的结构图
        Spring中的工厂类接口示意图
      • BeanFactory 和 ApplicationContext的区别和联系:
        • 联系:BeanFactory是Spring容器中的顶级接口, ApplicationContext是它的子接口。
        • 区别:BeanFactory 和 ApplicationContext创建对象的时间点不一样。ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。BeanFactory:什么使用什么时候创建对象。
      • Bean.xml文件中的细节详解:
        • bean标签:
          • 作用:用于配置让spring来创建对象,默认的情况下使用的是无参的构造函数来创建对象,如果没有无参的构造函数不能成功的创建对象。
          • bean标签中常用的属性:
            • id属性:对象在容器中的唯一标识,能够用来获取对象。
            • class属性 :指定的是要创建对象的全限定类名,默认的情况下使用的是无参的构造函数。
            • scope属性: 指定对象的作用范围,有五种取值(常用的是前两种):
              • singleton :默认值,单例的.
              • prototype :多例的.
              • request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
              • session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
              • global session :WEB 项目中,应用在 Portlet 环境(集群环境).如果没有 Portlet 环境那么globalSession 相当于 session.
            • init-method:指定类中初始化方法名称。
            • destroy-method:指定类中销毁方法名称。
          • bean对象的生命周期和作用范围:(Spring 中Bea对象的生命周期比较的复杂)
            • 单例对象: scope=“singleton”
              • 单例对象创建时机:使用的是立即加载
              • 作用范围: 每个应用只有一个该对象的实例,它的作用范围就是整个应用
              • 生命周期: 单例对象的创建与销毁 和 容器的创建与销毁时机一致
                • 对象出生: 当应用加载,创建容器时,对象就被创建
                • 对象活着: 只要容器存在,对象一直活着
                • 对象死亡: 当应用卸载,销毁容器时,对象就被销毁
                • 总结:单例对象的生命周期和容器的生命周期是一致的
            • 多例对象: scope=“prototype”
              • 多例对象的创建时机:使用的是延时加载
              • 作用范围: 每次访问对象时,都会重新创建对象实例.
              • 生命周期: 多例对象的创建与销毁时机不受容器控制
                • 对象出生: 当使用对象时,创建新的对象实例
                • 对象活着: 只要对象在使用中,就一直活着
                • 对象死亡: 当对象长时间不用时,被 java 的垃圾回收器回收了
                  在这里插入图片描述
          • Bean对象实例化的三种方式:
            • 第一种方式:使用默认无参构造函数:如果 bean 中没有默认无参构造函数,将会创建失败 (在Spring的配置文件中使用bean标签配置id和class属性,且没有其他的属性)
               <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/> 
              
            • 第二种方式:使用Spring中的静态工厂的方法来创建对象:(使用的是某个类中的静态方法来创建对象,并将对象存入spring和容器中)
              <!--factory-method 属性:指定生产对象的静态方法-->
              <bean id="accountService" class="com.itheima.factory.staticFactory" factory-method="getAccountService"></bean>
              
            • 第三种方式:使用spring来管理实例工厂-使用实例工厂中的普通方法来创建对象。(先是将工厂的创建交给Spring来管理,然后使用工厂的bean来调用里面的方法,从而来创建对象)
              <!--factory-bean 属性:用于指定实例工厂 bean 的 id。factory-method 属性:用于指定实例工厂中创建对象的方法。-->
              <bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean> 		
              <bean id="accountService" factory-bean="instancFactory" factory-method="createAccountService"></bean>
              
  3. Spring中的依赖注入:
    • 什么是以依赖注入:依赖注入(Dependency Injection) Spring中IoC的作用是降低程序之间的耦合,那么依赖注入就是IoC的具体实现方式。依赖关系的管理是Spring框架来进行维护的,依赖关系的具体的维护方式就是依赖注入。
    • 能够进行依赖注入的数据类型:三类
      • 基本的数据类型 和 String类型
      • 其他的bean类型:(在配置文件中或者是注解中配置过的bean 或者说是在spring容器中体现的类型)
      • 复杂类型 或者说是 集合类型(前三种能互用 后两种能互用)
         <property name="myStrings">
                    <array>
                        <value>AAA</value>
                        <value>BBB</value>
                        <value>CCC</value>
                    </array>
                </property>
                <property name="list">
                    <list>
                        <value>AAA</value>
                        <value>BBB</value>
                        <value>CCC</value>
                    </list>
                </property>
                <property name="mySet">
                    <set>
                        <value>AAA</value>
                        <value>BBB</value>
                        <value>CCC</value>
                    </set>
                </property>
                <property name="myMap">
                    <map>
                        <!--两种写法 第一种的方式较为简单-->
                        <entry key="testA" value="AAA"></entry>
                        <entry key="testB">
                            <value>BBB</value>
                        </entry>
                    </map>
                </property>
                <property name="properties">
                    <props>
                        <prop key="testA">AAA</prop>
                        <prop key="testB">AAA</prop>
                    </props>
                </property>
        
    • 依赖注入的方式:三种
      • 第一种使用构造器注入: 使用的标签是constructor-arg
        • 标签出现的位置是:bean标签的内部
        • constructor-arg标签的属性: 五种
          • index:用于指定要注入的数据给构造函数中,指定索引位置的参数赋值,索引的位置是从0开始的。(能独立的使用但是 需要记住所有的参数的顺序和类型)
          • name:用于指定给构造函数中指定名称的参数赋值 常用名称 主要是直接
          • type: 指定要注入的数据的类型 该数据类型也是构造函数中某个或者是某参数的类型 但是如果参数中有多个数据类型一致的话不行
            以上的三个用于指定给构造函数那个参数赋值
          • ref: 用于指定其他的bean类型 它指的就是在spring的ioc核心容器中出现过的bean对象
          • value: 用于提供基本数据类型和String类型的数据
        • 构造器注入的优缺点:
          • 优点:在获取bean对象时,注入数据是必要的操作,否则对象无法创建成功。 有些对象来创建时,有些属性是必须传入的,这样的方式就非常的适用。

          • 缺点:改变了bean对象的实例化方式,在我们创建对象的时候 如果用不要这些数据 也必须提供。(这样的方式不常用)

            <bean id="accountService" class="com.itheima.service.impl.IAccountServiceImpl">
                    <constructor-arg name="name" value="泰斯特"></constructor-arg>
                    <constructor-arg name="age" value="18"></constructor-arg>
                    <constructor-arg name="birthday" ref="now"></constructor-arg>
            </bean>
            <!--配置bean对象 配置一个日期对象使用constructor-arg标签中的ref属性来进行关联配置了全限定类名 spring就会使用反射 将对象进行创建 然后将对象存入spring核心容器中,使用id将对象拿出来-->
            <bean id="now" class="java.util.Date"></bean>
            
      • 第二种使用set方法注入:使用的标签是property
        • 标签出现的位置:同样是在bean标签的内部
        • property标签的属性:三种
          • name:用于指定注入时调用的set方法的名称 找到的是属性的值 不是成员变量的值
          • ref: 用于指定其他的bean类型 它指的就是在spring的ioc核心容器中出现过的bean对象
          • value: 用于提供基本数据类型和String类型的数据
        • set方法注入的优缺点:
          • 优点:创建对象没有明确的限制,可以使用默认的构造函数
          • 缺点: 如果某个成员必须有值,使用set方式无法保证一定注入。获取对象时set方法可能没有执行。
            <bean id="accountService2" class="com.itheima.service.impl.IAccountServiceImpl2" >
                <property name="name" value="test"></property>
                <property name="birthday" ref="now1"></property>
                <property name="age" value="18"></property>
            </bean>
            <bean id="now1" class="java.util.Date"></bean>
            
      • 第三种方法:使用注解注入【需要注意的一点是使用注解配置和使用XML文件进行配置实现的功能是一致的,都是为了降低程序之间的耦合性,只是配置的形式不同。且不同的公司对于注解形式和xml的形式的偏好程度不同,两种方式都要会使用。】
      • 导入外部文件使用的标签:
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <!--或者是-->
        <bean id="propertyPlaceholderConfigurer" class="org.springframework,beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>jdbc.properties<value/>
                </list>
            </property>
        </bean>
        
  4. 基于注解的IOC的详解:
    • 环境的搭建:
      • 导入相应的jar包,在bean.xml文件中,配置spring创建容器时扫描的包,注意的是这时使用的约束和使用xml进行配置的不同,需要一个名称为context名称空间和约束。context:component-scan标签 会扫描指定包下和子包的注解
        <?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">
                <!--
                   告知spring在创建容器的时候要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
                   context名称空间和约束。context:component-scan 会扫描指定包下和子包的注解
                -->
            <context:component-scan base-package="com.itheima"></context:component-scan>
        </beans>
        
    • 注解IOC常用的注解:
      • 分类:四种
        • 用于创建对象的:作用就是和在xml文件中编写一个bean标签实现的功能是一致的,但是只是添加了注解不能正常的运行 需要告知要扫描的包,在bean.xml中进行配置
          • @Component:
            • 作用:就是通过反射来创建对象,然后将对象存入Spring的IoC容器中。
            • 属性:String value() default ""; 用于指定bean对象的id,不写value的值,默认的就是当前类名,且首字母小写,但是类名的前两个字母都是大写,返回的Bean名称也是大写,即类名是IUserDao,bean名也是IUserDao。
          • @Repository @Service @Controller :
            • 作用:这三个注解的作用和@Component注解的作用是一致的,是spring框架为我们提供的明确使用的三层使用的注解,使三层对象更加的清晰
            • 作用的位置:
              • @Repository:一般使用在持久层(dao层)
              • @Service:一般使用在业务层(service层)
              • @Controller: 一般使用于表现层(controller层)
            • 属性:String value() default ""; 属性和@Component是一样的
        • 用于数据注入的:作用就是和在xml文件中编写一个property标签实现的功能是一致的
          • @Autowired
            • 作用:就是自动的按照类型注入,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去。
            • 使用的位置:@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
            • 和注解配置的不同: 进行注入的时候set方法不是必须的
            • 如果ioc容器中没有任何的bean类型和要注入的变量类型匹配, 就会报错。
          • @Qualifier
            • 作用:按照类注入的基础上再按照名称注入,它在给类成员注入的时候不能单独的使用。 但是在给方法参数使用的使用可以单独的使用。
            • 使用的位置:@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
            • 属性:value 用于指定要注入的bean的id 在给类成员注入的时候需要依赖于Autowired使用
          • @Resource(在容器中有多个类型相同的bean时,需@Autowired和@Qualifier组合使用才行,为了简化使用@Resource注解)
            • 作用: 直接按照bean的id进行注入, 且可以独立使用
            • 属性: name属性 注意的是不是value 用于指定bean的id
            • 注意:不是Spring框架中提供的注解,而是javax.annotation.Resource;
              以上的三种注解只能注入指定的bean类型的数据,而基本类型和String类型是不能使用上述注解来实现集合类型和导入的jar包中的类型的注入目前还是只能通过xml来实现(以后会讲纯注解的方式)
          • @Value
            • 作用:用于注入基本的数据类型和String类型,一般是将配置文件中的数据进行注入
            • 属性:String value();用于执行数据的值。 它能使用spel 也就是spring中的el表达式。SpEl的写法: 就是${表达式}或者是#{表达式}
        • 用于改变作用范围的 :作用就是在一个bean标签使用一个scope标签实现的功能是一致的
          • @Scope
            • 作用:用于指定bean的作用范围
            • 属性:看着像是两个其实就只有一个属性
              @AliasFor("scopeName")
              String value() default "";
              @AliasFor("value")
              String scopeName() default "";
              
              • value指定范围的取值 常用的取值有:singleton prototype 不写默认的情况下是单例的
            • 作用的位置:@Target({ElementType.TYPE, ElementType.METHOD})
        • 和生命周期相关的:作用就是在一个bean标签使用一个init-method 和使用一个destroy-method标签是一致的。
          • @PreDestroy
            • 作用:用于指定销毁方法
          • @PostConsturct
            • 作用:用于指定初始化方法
    • 纯注解方式实现:
      • 注解方式存在的问题:使用注解的形式还是离不开bean.xml配置文件,实现纯注解的方式就是,将bean.xml文件中的内容也通过注解实现。如开启注解扫描、配置数据源的信息等。
      • 注意:选择哪种配置的原则是简化开发和配置方便,而非追求某种技术。不要因小失大(使用框架的目的是为了简化开发 不是炫技)
      • 纯注解方式需要的注解:
        • @Configuration:
          • 作用:指定的是当前类是一个spring的配置类,在创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class) 而不是使用ClassPathXmlApplicationContext实现类进行容器的创建。
          • 属性: value 指定配置类的字节码
          • 作用的位置:类上
        • @ComponentScan:
          • 作用:用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
            <context:component-scan base-package="com.itheima"/>是一样的。
          • 属性:basePackages 别名是 value:用于指定要扫描的包。和该注解中的 value 属性作用一样。
          • 作用的位置:类上
        • @Bean
          • 作用:表明使用此方法创建一个对象,并且放入 spring 容器。
          • 属性:name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)
          • 作用的位置:方法上
        • @PropertySource
          • 作用: 用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
          • 属性:value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
          • 作用的位置:类上
        • @Import
          • 作用:用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问题。
          • 属性:value[]:用于指定其他配置类的字节码。
          • 作用的位置:类上
  5. Spring 整合 Junit
    • 注意:当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上
    • 步骤:
      • 导入junit 的必备 jar 包 注意的是需要spring aop的支持
      • 使用@RunWith 注解替换原有运行器
        @RunWith(SpringJUnit4ClassRunner.class)
        public class XxxTest {
        }
        
      • 使用@ContextConfiguration 指定 spring 配置文件的位置
        • 属性:
          • locations 属性:用于指定配置文件的位置。如果是类路径下,需要classpath:表明
          • classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(locations= {"classpath:bean.xml"})
        public class  XxxTest {
        }
        
      • 使用@Autowired 给测试类中的变量注入数据
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(locations= {"classpath:bean.xml"})
        public class XxxTest {
        	@Autowired
        	private IAccountService as; 
        	}
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上山打卤面

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值