选择 10/10

  1. 依赖注入的概念
    控制反转(Inversion of Control,IoC)是一个比较抽象的概念,是Spring框架的核心,用来消减计算机程序的耦合问题。依赖注入(Dependency Injection,DI)是IoC的另外一种说法,只是从不同的角度,描述相同的概念。下面通过实际生活中的一个例子解释IoC和DI。
    当人们需要一件东西时,第一反应就是找东西,例如想吃面包。在没有面包店和有面包店两种情况下,你会怎么做?在没有面包店时,最直观的做法可能是按照自己的口味制作面包,也就是需要主动制作一个面包。然而,时至今日,各种面包店盛行,当你不想自己制作面包时,可以去面包店,选择你喜欢的面包。注意你并没有制作面包,而是由店家制作,但是完全符合你的口味。
    上面只是列举了一个非常简单的例子,但包含了控制反转的思想,即把制作面包的主动权交给店家。下面通过面向对象编程思想,继续探讨这两个概念。
    当某个Java对象(调用者,例如你)需要调用另一个Java对象(被调用者,即被依赖对象,例如面包)时,在传统编程模式下,调用者通常会采用“new被调用者”的代码方式来创建对象(例如你自己制作面包)。这种方式会增加调用者与被调用者之间的耦合性,不利于后期代码的升级与维护。
    当Spring框架岀现后,对象的实例不再由调用者来创建,而是由Spring容器(例如面包店)来创建。Spring容器会负责控制程序之间的关系(例如面包店负责控制你与面包的关系),而不是由调用者的程序代码直接控制。这样,控制权由调用者转移到Spring容器,控制权发生了反转,这就是Spring的控制反转。
    从Spring容器角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它所依赖的实例,这就是Spring的依赖注入,主要目的是为了解耦,体现一种“组合’‘的理念。
    综上所述,控制反转是一种通过描述(在Spring中可以是XML或注解)并通过第三方产生或获取特定对象的方式。在Spring中实现控制反转的是ToC容器,其实现方法是依赖注入。

Spring IoC 容器 (ApplicationContext) 负责创建和注入 Bean Spring 提供使用 XML配置、注解、 Java 配置以及 groovy 配置实现 Bean 的创建和注入。本书尽量使用注解 (@Component @Repository @Service 以及@ Controller 等业务 Bean 的配置)和 Java 配置(全局配置如数据库、 MVC 等相关配置)完全代替 XML 配置,这也是 Spring Boot 推荐的 配置方式
下面通过一个简单实例向读者演示基于注解的依赖注入的使用过程
1.导入Spring AOP 的JAR 包
2.创建DAO层
在chi _ 2应用的src中,创建annotation, dao包,该包下创建TestDao接口和TestDaoImpl实现类,并将实现类TestDaoImpl使用©Repository注解标注为数据访问层。

  1. // TestDao的代码如下
  2. package annotation.dao;
  3. public interface TestDao {
  4. public void save();
  5. }
// TestDaoImpl的代码如下
package annotation.dao;
import org. springframework. stereotype. Repository;
@Repository("testDao")
/ ** 
    相当于@Repository,
    但如果在 service 层使用@Resource(name = "testDao")注入 Bean, testDao 不能省略。
**/

public class TestDaoImpl implements TestDao{
    @Override
    public void save() {
        System, out. println( "testDao save**);
    }
}
  1. 创建Service层
    在chl_2应用的src中,创建annotation.service包,该包下创建TestService接口和TestSevicelmpl实现类,并将实现类TestServicelmpl使用@ Service注解标注为业务逻辑层。
    // TestService的代码如下
    package annotation.service;
    public interface TestService {
     public void save();
    }
    
    // TestServicelmpl 的代码如下
    package annotation.service;
    import javax.annotation.Resource;
    import org. springframework. stereotype. Service;
    import annotation.dao.TestDao;
    @ Service("testService")    //相当于@ Service
    public class TestSevicelmpl implements TestService{
     @ Resource(name = "testDao")
     private TestDao testDao;
    / **
     相当于@Autowired, 
     @Autowired默认按照Bean类型注入
    ** /    
    @Override
     public void save() {
         testDao.save();
         System, out. println( "testService save");
     }
    }
    
  2. 创建Controller 层
    在chl_2 应用的src 中,创建annotation.controller 包,该包下创建TestController 类,并将TestController类使用@Controller注解标注为控制器层。
    // TestController的代码如下
    package annotation. controller;
    import org. springframework. beans, factory, annotation. Autowired;
    import org. springframework. stereotype. Controller;
    import annotation, service. TestService;
    @Controller
    public class TestController {
     @Autowired
     private TestService testService;
     public void save() {
         testService. save();
         System, out. println("testcontroller save");
     }
    }
    
  3. 创建配置类
    本书尽量不使用Spring的XML配置文件,而使用注解和Java配置。因此,在此需要使用©Configuration创建一个Java配置类(相当于一个Spring的XML配置文件),并通过 @ComponentScan扫描使用注解的包(相当于在Spring的XML配置文件中使用<context: component-scan base-package= “Bean 所在的包路径”/〉语句)。
    在chl_2应用的annotation包下,创建名为ConfigAnnotation的配置类。 ```java // Config Annotation 的代码如下: package annotation; import org. springframework. context, annotation. ComponentScan; import org.springframework. context, annotation. Configuration; @ Configuration //声明当前类是一个配置类(见1.3.4节)/相当于一个Spring的XML配置文件 @ComponentScan(“annotation’) // 自动扫描annotation包下使用的注解,并注册为Bean / 相当于在Spring 的XML 配置文件中使用< context:component - scan base - package = “Bean 所在的包路径”/>语句
  • / public class ConfigAnnotation { } ```
  1. 创建测试类
    在chl_2应用的annotation包下,创建测试类Test Annotation,具体代码如下:
    package annotation;
    import org. springframework. context, annotation. AnnotationConf igApplicationContext;
    import annotation.controller. Testcontroller;
    public class TestAnnotation {
     public static void main(String[ ] args) {
         // 初始化Spring 容器ApplicationContext
         AnnotationConfigApplicationContext appCon =
         new AnnotationConfigApplicationContext(ConfigAnnotation. class); TestController tc = appCon.getBean(TestController. class);
         tc.save(); 
         appCon.close();
     }
    }
    
  2. 运行结果
    运行测试类TestAnnotation的main方法,结果如图1. 12所示。
    image.png

既然spring创建对象是通过依赖注入来完成的,那就要讲到依赖注入的三种方式了。一般来说,依赖注入可以分为三种方式。

  • 构造器注入。
  • setter注入。
  • 接口注入。

构造器和setter注入是主要的方式,接口注入是从别的地方注入的方式。


  1. AOP的概念

  1. applicationContext接口(spring容器)的概念
    image.png

Spring 的核心容器是其他模块建立的基础,由 Spring core Spring-beans 、 Spring-context 、Spring context support 、Spring expression (Spring 表达式语言)等模块组成。

  • Spring core 模块:提供了框架的基本组成部分,包括控制反转 (Inversion of Control, IoC) 和依赖注入 (Dependency Injection, DI) 功能。
  • Spring beans 模块:提供了 BeanFactory ,是工厂模式的一个经典实现, Spring 将管理对象称为 Bean
  • Spri ng-con text 模块:建立在 Core Beans 模块基础上,提供一个框架式的对象访问 方式,是访问定义和配置的任何对象的媒介 ApplicationContext 接口是 Context 模块的 焦点。
  • Spring context-support 模块:支待整合第 方库到 Spring 应用程序上下文,特别是用 于高速缓存 (EhCache ]Cache) 和任务调度 (Common] Quartz) 的支持
  • Spring expression 模块:提供了强大的表达式语言去 支待运行时查询和操作对象图。这是对 JSP 2. 规范中规定的统一表达式语言 (Unified EL) 的扩展 。该语言支待设置和获取属性值、属性分配、方法调用、访问数组、集合和索引器的内容、逻辑和算术运算、变量命名 以及从 Spring IoC 容器中以名称检索对象。它还支持列表投影、选择以及常见的列表 聚合

Spring提供了两种不同的类型的容器

  • Spring BeanFactory容器:它是最简单的容器,给 DI 提供了基本的支持
  • ApplicationContext容器 :ApplicationContext 容器继承自BeanFactory,它包括 BeanFactory 容器的所有功能,所以通常建议使用。

  1. Spring事务管理的概念
    image.png
    image.png
    image.png
    image.png

  1. Spring概念
    Spring是一个轻量级Java开发框架,最早由RodJohnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/ EEfull-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。
    6&7 看程序写结果 Spring 找出所有在Spring容器中定义的bean对象
    方法一:在初始化时保存ApplicationContext对象
    ApplicationContext ac =new FileSystemXmlApplicationContext("applicationContext.xml");
    ac.getBean("userService");
    //如:<bean id="userService" class="com.cloud.service.impl.UserServiceImpl"></bean>
    
    方法二:通过Spring提供的工具类获取ApplicationContext对象
    ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
    ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
    ac1.getBean("beanId");
    ac2.getBean("beanId");
    
  2. Springmvc的整个工作过程(手动mvc项目)
    9. Spring和mybatis的整合(整合步骤)
    10. Spring和mybatis的整合

    填空 5/10分

  3. Spring中的通知注解4类6种写法
    1.环绕通知:环绕通知是在目标方法执行前和执行后实施增强,可以应用于日志记录、事务处理等功能。
    2. 前置通知:前置通知是在目标方法执行前实施增强,可以应用于权限管理等功能。
    3. 后置返回通知:后置返回通知是在目标方法成功执行后实施增强,可以应用于关闭流、删除临时文件等功能。
    4. 后置(最终)通知:后置通知是在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该通知,可以应用于释放资源。
    5. 异常通知:异常通知是在方法抛出异常后实施增强,可以应用于处理异常、记录日志等功能。
    6. 引入通知:引入通知是在目标类中添加一些新的方法和属性,可以应用于修改目标类(增强类)。

@Before:前置通知,在方法执行之前执行
@After:后置(最终)通知,在方法执行之后执行(无论是否发生异常)还不能访问目标方法执行的结果
@AfterRuturning:后置返回通知,在方法正常结束后 返回结果之后执行 可以访问方法的返回值
@AfterThrowing:异常通知,在方法抛出异常之后
@Around:环绕通知,围绕着方法执行

package cn.itcast.e_annotationaop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

//通知类
@Aspect
//表示该类是一个通知类
public class MyAdvice {
    @Pointcut("execution(* cn.itcast.service.*ServiceImpl.*(..))")
    public void pc(){}//抽取相同的execution,方便管理。
    //前置通知
    //指定该方法是前置通知,并制定切入点
    @Before("MyAdvice.pc()")
    public void before(){
        System.out.println("这是前置通知!!");
    }
    //后置通知
    @AfterReturning("execution(* cn.itcast.service.*ServiceImpl.*(..))")
    public void afterReturning(){
        System.out.println("这是后置通知(如果出现异常不会调用)!!");
    }
    //环绕通知
    @Around("execution(* cn.itcast.service.*ServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("这是环绕通知之前的部分!!");
        Object proceed = pjp.proceed();//调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return proceed;
    }
    //异常通知
    @AfterThrowing("execution(* cn.itcast.service.*ServiceImpl.*(..))")
    public void afterException(){
        System.out.println("出事啦!出现异常了!!");
    }
    //后置通知
    @After("execution(* cn.itcast.service.*ServiceImpl.*(..))")
    public void after(){
        System.out.println("这是后置通知(出现异常也会调用)!!");
    }
}
  1. Spring中AOP注解(尤其在织入时)写法//写在方法上那一串东西
  1. SpringAOP中的切面都包含着什么(4个)切面、切点、织入,通知之间的关系?
    1) 切面
    切面(Aspect)是指封装横切到系统功能(如事务处理)的类。
    3) 切入点
    切入点(Pointcut)是指那些需要处理的连接点。在Spring AOP中,所有的方法执行都是连接点,而切入点是一个描述信息,它修饰的是连接点,通过切入点确定哪些连接点需要被处理。
    4) 通知(增强处理)
    由切面添加到特定的连接点(满足切入点规则)的一段代码,即在定义好的切入点处所要执行的程序代码。可以将其理解为切面开启后,切面的方法。因此,通知是切面的具体实现。
    8) 织入
    织入(Weaving)是将切面代码插入目标对象上,从而生成代理对象的过程。根据不同的实现技术,AOP织入有3种方式:

    • 编译器织入,需要有特殊的Java编译器;
    • 类装载器织入,需要有特殊的类装载器;
    • 动态代理织入,在运行期为目标类添加通知生成子类的方式。

Spring AOP框架默认釆用动态代理织入,而AspectJC(基于Java语言的AOP框架)采用编译器织入和类装载器织入。


  1. Spring注解装配时有2种方式byName和byType?
    bytype -> @Autowired byname -> @Resource

  1. Spring当中单例和多态怎么设置?用哪个注解来设置?
    @Scope(“prototype”)
    //默认为 singleton 相当于 @Scope(“singleton”)

简答 3/30分

  1. Spring、springmvc、springboot之间有什么区别
    答:SpringBoot是一个大框架,里面包含了许多的东西,习惯优于配置,降低了项目搭建的难度,其中spring就是最核心的内容之一,spring mvc 是Spring的一个模式,只是spring 处理web层请求的一个模块,提供了一个轻度耦合的方式来开发Web应用;SpringMVC需要使用到TomCat服务器,SpringBoot的话是内嵌了Tomcat服务器的。

  2. Springboot有哪些功能(书上原题)
    答:
    1.约定优于配置,提供“入门”依赖项以简化构建配置
    2.可以用jar包的形式独立运行
    3.直接嵌入Tomcat、Jetty或Undertow,无需部署WAR文件
    4.提供starter简化Maven配置
    5.自动配置Spring
    6.提供准生产的应用监控
    7.无代码生成和XML配置

  3. Springmvc中有四大注解:组件、服务、仓储、控制类……功能是一致的吗?有什么区别?
    答:
    image.png
    它们都是声明Bean的注解

  • @Service用于标注业务逻辑层组件(service层)
  • @Controller用于标注控制器组件
  • @Repository用于将数据访问层(DAO)的类标识为Bean,即注解数据访问层Bean
  • @Component是一个泛化的概念,通用标注,在不清楚使用哪个注解的时候,可以使用Component通用注解
  1. Spring中支持几种(BeanScope)作用域?分别说一下
    答:image.png
    1.singleton:单例模式,默认作用域
    2.prototype:原型模式
    3.request:HTTP请求
    4.session:会话
    5.application:为每个ServletContext对象创建一个实例,同一个应用共享一个Bean实例。
    6.websocket:为websocket对象创建一个实例
    singleton和prototype是最常用的两种,后面4种作用域仅使用在Web Spring应用程序上下文。
    singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例
    prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例
    只有在 Web 应用中使用Spring时,request、session、global-session 作用域才有效
    request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个新实例,即每次 HTTP 请求将会产生不同的 bean 实例。
    session:同一个 Session 共享一个 bean 实例。

  2. Springboot的核心注解是什么?这个注解是由哪几个注解组成的?
    答:Spring Boot 的核心注解是程序入口类使用@SpringBootApplication将该入口类标注为应用的启动类,
    主要组合包含了以下 3 个注解:

  • @SpringBootConfiguration:代替@Configuration 注解,是springboot的配置注解。
  • @EnableAutoConfiguration:让springboot根据当前应用项目所依赖的jar自动配置项目的相关配置
  • @ComponentScan:让springboot自动扫描@SpringBootApplication所在类的同级包以及它的子包中的配置

上机(50%)

  1. ssm和springboot整合(使用注解完成)
    2. 单表操作(条件查询,没有删除,带一个修改/添加)
    3. 查询时结果用json进行显示
    4. 截图要有时间/个人信息
    5. 项目创建和最后修改时间,项目大小