资讯详情 Java EE 进阶:5. Spring IoCDI(第三弹):Spring DI
📅 2026/11/1 1:53:02
目录4. DI 详解4.1 属性注入4.2 构造方法注入4.3 Setter 注入4.4 三种注入优缺点分析4.5 Autowired 存在问题方式一Primary方式二Qualifier第一种用法加在属性上第二种用法加在参数上方式三Resource常见面试题:频率比较高小结5.练习6.总结6.1 SpringSpring Boot 和 Spring MVC 的关系以及区别6.2 bean 的命名6.3 常见面试题书接上文Java EE 进阶5. Spring IoCDI第二弹Spring IoC~~4. DI 详解上面我们讲解了控制反转 IoC 的细节接下来呢我们学习依赖注入DI的细节我们把对象交给 Spring 进行管理了既然我们能放自然就能取~~什么是依赖上述代码中 BookService 依赖 BookDaoBookDao 就是 BookService 的依赖如果 BookService 想要正常工作那么就需要有 BookDao 才能正常工作BookDao 就是依赖~~而 DI 表示依赖注入依赖注入是一个过程是从容器当中取出对象注入到 BookDao 里这就是依赖注入IoC 讲的是 Bean 的存储DI 讲的是 Bean 的获取~~闲聊IoC 和 DI 也是 Spring 中常见的面试题因为除了这俩也没啥能问的~~在上面程序案例中我们使用了Autowired 这个注解完成了依赖注入的操作.简单来说, 就是把对象取出来放到某个类的属性中.在一些文章中, 依赖注入也被称之为 对象注入, 属性装配, 具体含义需要结合文章的上下文来理解关于依赖注入, Spring也给我们提供了三种方式:1. 属性注入(Field Injection)2. 构造方法注入(Constructor Injection)3. Setter 注入(Setter Injection)接下来我们分别来看。下面我们按照实际开发中的模式将 Service 类注入到 Controller 类中。4.1 属性注入在上述代码中bookDao 就是 BookService 的属性所以是属性注入~~属性注入是使用 Autowired 实现的将 Service 类注入到 Controller 类中.Service 类的实现代码如下Service//此时也是交给Spring管理了 public class UserService { public void print(){ System.out.println(do Service); } }Controller 类的实现代码如下Controller public class HelloController { Autowired//注入userService此时userService就有值了 private UserService userService; public void print(){ System.out.println(do Controller); userService.print(); } }此时 Autowired 就会从 Spring 容器中找到 service 类型的对象并且赋值给这个属性获取 Controller 中的 print 方法SpringBootApplication //加上这个注解之后不管这个类名叫什么它都是一个启动类 public class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下文对象直接使用父类接收 ApplicationContext context SpringApplication.run(SpringIocDemoApplication.class, args); //DI测试 //从 Spring 上下文中获取对象 HelloController beancontext.getBean(HelloController.class); bean.print(); } }程序执行后就会调用 userService.print();Controller public class HelloController { Autowired//注入userService此时userService就有值了 private UserService userService; public void print(){ System.out.println(do Controller); userService.print(); } }然后就会打印 “do Service”Service//此时也是交给Spring管理了 public class UserService { public void print(){ System.out.println(do Service); } }最终结果如下发现确实注入进来了userService 也是有值的~~去掉 Autowired , 再运行一下程序看看结果也就是说我们把 Autowired 去掉后userService 就是一个普通声明了这个普通说明默认是为 null 的~~这也验证了 Autowired从 Spring 容器中根据类型获取对象并赋值~~那么又有一个问题了既然是从 Spring 容器中获取对象那么容器中必须要有这个对象才可以没有的话是注入不进来的而我们刚才能获取到是因为加了 Service 这个注解如果没有这个注解呢我们去掉 Service再来尝试一下//Service//此时也是交给Spring管理了 public class UserService { public void print(){ System.out.println(do Service); } }发现都服务都启动不起来出现这个报错信息就说明 Spring 容器中不存在这个对象以上两个错误信息一个是属性未赋值一个是 Spring 容器中不存在这个对象这是两个不同的异常信息需要注意分辨~~注意Autowired 是根据类型取查找的所以我们的名称是任意写的比如可以写成 us而不要求一定与 UserService.java 中 Bean 的名称相同Controller public class HelloController { Autowired//注入userService此时userService就有值了 private UserService us; public void print(){ System.out.println(do Controller); us.print(); } }那就来问题了既然是根据类型找那上一节我们学 IoC 的时候知道Bean 的话一个类型是可以有多个对象的那么有多个对象的时候 Autowired 注入是不是就失败了呢这确实是个问题我们在下面的 4.5 Autowired 进行演示和讲解~~4.2 构造方法注入构造方法注入是在类的构造方法中实现注入如下代码所示Controller public class HelloController { //构造方法注入 private UserService us; public HelloController(UserService us){ this.usus; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); } }此时我们发现也是可以运行成功的证明 us 中也确实有值同样的我们把构造方法去掉后就只剩下一个声明了自然 us 值就为 null 了另外我们说当我们构造了有参的构造函数之后无参的构造函数默认就会没有了所以我们一般要及时把无参构造函数给补上因为有些情况可能会出错比如说像 json 的一些序列化就可能有问题~~那么现在问题又来了当我们加上无参构造函数之后貌似又出现了新的问题Controller public class HelloController { //属性注入 //Autowired//注入userService此时userService就有值了 //private UserService us; //构造方法注入 private UserService us; public HelloController(){ } public HelloController(UserService us){ this.usus; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); } }此时又变成这样了这就涉及到了交给 Spring 管理之后Spring 创建对象是怎么创建的底层原理是依靠 反射 来创建对象的~~反射知识点Java数据结构——11.反射 枚举 lambda《干货笔记》反射 这一概念是我们数据结构阶段存在感非常低的一个知识点调用的也是构造函数只不过不是直接的而此时我们有两个构造方法一个有参的一个无参的到底调用哪个呢默认是用的无参的那么我们现在把无参的给去掉再新加一个属性看两个构造函数它调用的是哪个Controller public class HelloController { //构造方法注入 private UserService us; private UserConfig userConfig; // public HelloController(){ // // } public HelloController(UserConfig userConfig, UserService us) { this.userConfig userConfig; this.us us; } public HelloController(UserService us){ this.usus; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }此时我们发现报错信息又发生了变化闲聊Java EE 阶段学会看错误日志非常重要~~错误日志要从下往上看因为堆栈信息是从下往上打的~~如果能在最底层看懂哪里出错了那上面那一大堆就不用看了否则就依次往上看~~上面错误日志中 instantiate 表示实例化上述错误日志就是说我们没找到默认的无参构造方法那么就得出结论了当只有一个构造方法时就只能用这个了如果出现多个构造方法就去找默认的无参构造方法没找到就报错~~那么我们如何指定构造方法呢还是使用 AutowiredController public class HelloController { //构造方法注入 private UserService us; private UserConfig userConfig; // public HelloController(){ // // } Autowired public HelloController(UserConfig userConfig, UserService us) { this.userConfig userConfig; this.us us; } public HelloController(UserService us){ this.usus; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }此时我们发现就成功了此时我们是给带有两个参数的构造方法带上 Autowired如果是只给带一个参数的构造方法带的话那么另一个就会因取值为 null 而报错Controller public class HelloController { //构造方法注入 private UserService us; private UserConfig userConfig; // public HelloController(){ // // } // Autowired public HelloController(UserConfig userConfig, UserService us) { this.userConfig userConfig; this.us us; } Autowired public HelloController(UserService us){ this.usus; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }总结如果类只有一个构造方法那么 Autowired 注解可以省略如果类中有多个构造方法默认构造方法是无参的构造方法如果没有就会报错也可以用 Autowired 来明确指定到底使用哪个构造方法4.3 Setter 注入Controller public class HelloController { //setter方法注入 private UserService us; private UserConfig userConfig; public void setUs(UserService us) { this.us us; } public void setUserConfig(UserConfig userConfig) { this.userConfig userConfig; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }启动服务后发现 us 值为 null还没到 userConfig 就报错了Setter 注入和属性的 Setter 方法实现类似只不过在设置 set 方法的时候需要加上 Autowired 注解 如下代码所示Controller public class HelloController { //setter方法注入 private UserService us; private UserConfig userConfig; Autowired public void setUs(UserService us) { this.us us; } public void setUserConfig(UserConfig userConfig) { this.userConfig userConfig; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }发现这时候 us 就有值了只不过 userConfig 还没有值所以报错当我们给 userConfig 也加上 Autowired 之后就可以了Controller public class HelloController { //setter方法注入 private UserService us; private UserConfig userConfig; Autowired public void setUs(UserService us) { this.us us; } Autowired public void setUserConfig(UserConfig userConfig) { this.userConfig userConfig; } public void print(){ System.out.println(do Controller); System.out.println(us); us.print(); userConfig.print(); } }此时 us 和 userConfig 就都注入进来了4.4 三种注入优缺点分析这部分也是个面试题只不过频率很低大家了解就行了也不建议去背理解就行了~~1属性注入①优点: 简洁使用方便②缺点:▪ 只能用于 IoC 容器如果是非 IoC 容器不可用并且只有在使用的时候才会出现 NPE空指针异常说白了脱离 Spring 就用不了了~~▪ 不能注入一个 Final 修饰的属性语法就报错这个就与我们 final 的语法有关了对于 final 的变量在这里就两种写法第一种new 一个对象初始化那我都 new 了还 Autowired 干啥呀那我不用得了呗不从 Spring 拿了我都自己 new 完了~~所以不行~~第二种构造方法初始化那我都用构造方法了那不就是构造方法注入了吗我直接在 构造方法 里赋值了不香吗所以不行~~注意Autowired 只会对下一行代码生效不会对下面所有属性生效2构造函数注入(Spring 4.X推荐的)我们此时的 Spring 版本也可以自行查看是 7.0.10①优点:▪ 可以注入 final 修饰的属性上面已经说过了▪ 注入的对象不会被修改其实这点是针对 set 方法来说的Autowired public HelloController(UserConfig userConfig, UserService us) { this.userConfig userConfig; this.us us; }当我们加上 Autowired 之后表示我在创建对象的时候使用的构造方法就是这个了在这个地方给它赋值了之后就不会再被修改了~~▪ 依赖对象在使用前一定会被完全初始化因为依赖是在类的构造方法中执行的而构造方法是在类加载阶段就会执行的方法.这个就涉及到我们 Java EE 初阶 JVM 类加载机制相关的知识了最先执行的就是构造方法所以刚创建对象的时候就有值了Java EE9.JVM▪ 通用性好, 构造方法是 JDK 支持的, 所以更换任何框架,他都是适用的就是说不局限于 Spring 框架②缺点:▪ 注入多个对象时, 代码会比较繁琐3Setter注入(Spring 3.X推荐的)为啥不同版本推荐不同的注入咱也不知道可能换领导了吧使用习惯不一样~~①优点: 方便在类实例之后, 重新对该对象进行配置或者注入也就是说既然构造方法是个方法那我们就可以对其重复使用的~~②缺点:▪ 不能注入一个 Final 修饰的属性▪ 注入对象可能会被改变, 因为setter方法可能会被多次调用, 就有被修改的风险.极限的优点就是缺点~~更多DI相关内容参考: Dependencies :: Spring Framework4.5 Autowired 存在问题闲聊Setter 注入是 Spring 3.X 推荐的构造方法注入是 Spring 4.X 推荐的而咱们程序员呢就推荐 属性注入因为简单~~当同一类型存在多个 bean 时, 使用Autowired会存在问题我们先用一个对象试试UserService.javaService//此时也是交给Spring管理了 public class UserService { Autowired private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }StudentComponrnt.javaComponent public class StudentComponent { Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } // Bean // public Student s2(String name){ // return new Student(name,12); // } }启动类SpringBootApplication public class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下文对象直接使用父类接收 ApplicationContext context SpringApplication.run(SpringIocDemoApplication.class, args); //从Spring容器中拿到UserService并调用它的方法 UserService beancontext.getBean(UserService.class); bean.print(); } }运行结果没问题注意此时 s3 和 s4 是两个名而已就好像 CoderYanger 的大小名指的其实是一个人~~那如果我们再加一个对象 s2 呢Component public class StudentComponent { Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } Bean public Student s2(String name){ return new Student(name,12); } }运行结果Autowried 和 构造方法一样当只有一个的时候没得选只能用这一个当出现多个的时候就懵圈了~~Action 里的内容就跟咱上网搜资料一样有时候可用有时候不可用但咱这次的 Action 是可用的其中 Primary 在学习数据库的时候见到过主键整体就是在说让你标识一个为默认的或者使用 Qualifier 去指定 Bean这两个注解就是我们下面要说的解决方案~~如何解决上述问题呢Spring提供了以下几种解决方案• Primary• Qualifier• Resource方式一Primary使用Primary注解当存在多个相同类型的Bean注入时加上Primary注解来确定默认的实现Component public class StudentComponent { Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } Primary Bean public Student s2(String name){ return new Student(name,12); } }发现默认就使用第二个对象了加在第一个对象上面Component public class StudentComponent { Primary Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } // Primary Bean public Student s2(String name){ return new Student(name,12); } }此时默认就使用第一个对象了方式二Qualifier第一种用法加在属性上使用 Qualifier 注解指定当前要注入的 bean 对象。 在Qualifier的 value 属性中指定注入的 bean 的名称也就是在这个位置我们在 Autowired 中发现它只有一个属性默认为 true也就是说 Autowired 必须要执行的我们也没有地方去给 Autowired 设置名称Spring 有个解决问题的特点一个注解搞不定就两个注解搞定两个注解还搞不定就三个注解搞定……所以此处用 Qualifier 去指定它的名称。因为它的源码里有 value• Qualifier注解不能单独使用必须配合Autowired使用Service//此时也是交给Spring管理了 public class UserService { Qualifier(s3)//指定bean名称为s3 Autowired private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }此时启动服务后拿到的就是 s3 的对象当我们改成 s2 时Service//此时也是交给Spring管理了 public class UserService { Qualifier(s2)//指定bean名称为s2 Autowired private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }此时拿到的对象就是 s2第二种用法加在参数上看完 方式三Resource 再来看这一条~~Qualifier 源码中写了可以加在参数上此时代码Service//此时也是交给Spring管理了 public class UserService { Resource(names2) private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }Resource 用到了 s2s2 在这里用到了 String n但是 n 上面有 name 和 name2 两个应该用哪个Component public class StudentComponent { Primary Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } Bean public String name2(){ return Ayanger2; } Bean public Student s2(String n){ return new Student(n,12); } }运行后发现报错s2 需要一个单例但是却发现两个此时就可以用 Qualifier 去指定名称比如 name2Component public class StudentComponent { Primary Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } Bean public String name2(){ return Ayanger2; } Bean public Student s2(Qualifier(name2) String n){ return new Student(n,12); } }此时拿到的就是 name2 对应的对象当然改成 name 后就是拿到的 name 对应的对象~~方式三Resource上面两个都是 Spring 的注解都是 Autowired 的解决方式是根据类型的我们没办法去指定名称而 Resource 却是来自 JDKimport jakarta.annotation.Resource;闲聊Java EE 在 2018 年的时候就更名为 jakarta EE 了在 JDK 8 的时候这个注解就是在 JDK 里面的在 2017 年的时候就把 Java EE 捐给 eclipse 了然后 eclipse 就要求他使用 Java 这个名字所以这时候关于 Java EE 的部分就拆出来了然后就放在 Jakarta 里面了所以虽然是拆出来了但是我们还是倾向于认为它还是 JDK 提供的东西我们的注解也不是说 Spring 才有的这并不是什么很新鲜的事情JDK 中就存在很多注解以上就都是 JDK 提供的准确而言是 Jakarta 提供的~~使用Resource注解是按照 bean 的名称进行注入。通过 name 属性指定要注入的 bean 的名称Service//此时也是交给Spring管理了 public class UserService { Resource(names3) private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }我们此时发现打印的就是 s3 的对象当我们把名称改为 s2 之后Service//此时也是交给Spring管理了 public class UserService { Resource(names2) private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }此时打印的就是 s2 的对象答疑Q1为啥 Spring 中只提到了前两种解决方式呢因为 Primary 和 Qualifier 都是 Spring 自己的解决方式而下面的 Resource 是 JDK 的解决方式就好比于出现问题优先内部解决~~Q2那未来工作中哪种注解比较常用呢Qualifier 和 ResourcePrimary 使用的非常少基本见不到~~依赖注入通常使用 Autowired 和 Resource放在参数就通常使用 Qualifier~~常见面试题:频率比较高Autowird 与 Resource的区别• Autowired 是 spring 框架提供的注解而 Resource 是 JDK 提供的注解• Autowired 默认是按照类型注入而 Resource 是按照名称注入.闲聊这句话并不严谨但是面试官爱听~~因为Resource 需要类型一样才能按照名称注入不然是注入不了的所以要 类型名称都要满足的Autowired 就是类型但是名称也是起一点点作用的我们下面来演示一下Component public class StudentComponent { Bean({s3,s4}) public Student s1(){ return new Student(CoderYanger,21); } Bean public String name(){ return Ayanger; } Bean public String name2(){ return Ayanger2; } Bean public Student s2(Qualifier(name2) String n){ return new Student(n,12); } }SpringBootApplication //加上这个注解之后不管这个类名叫什么它都是一个启动类 public class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下文对象直接使用父类接收 ApplicationContext context SpringApplication.run(SpringIocDemoApplication.class, args); //从Spring容器中拿到UserService并调用它的方法 UserService beancontext.getBean(UserService.class); bean.print(); } }当名称为 s1 时Service//此时也是交给Spring管理了 public class UserService { Autowired private Student s1; public void print(){ System.out.println(do Service); System.out.println(s1); } }发现报错了只需要一个但是找到了两个我们前面说过这个名称无所谓叫啥都行那么我们接下来改成 s2Service//此时也是交给Spring管理了 public class UserService { Autowired private Student s2; public void print(){ System.out.println(do Service); System.out.println(s2); } }我们发现它又不报错了找到了难道名称是有效的吗再改成 s3Service//此时也是交给Spring管理了 public class UserService { Autowired private Student s3; public void print(){ System.out.println(do Service); System.out.println(s3); } }我们发现名称确实是有效的这就是这句话不严谨的原因~~相比于 Autowired 来说Resource 支持更多的参数设置例如 name 设置根据名称获取 Bean.闲聊所以即使不严谨也要先回答面试官爱听的Autowired 按照类型Resource 按照名称~~Autowired装配顺序需要掌握这也体现出了 Qualifier 比属性名称优先级要高我们也可以在代码中体现Service//此时也是交给Spring管理了 public class UserService { Qualifier(s2)//指定bean的名称为s2 Autowired private Student s3; public void print(){ System.out.println(do Service); System.out.println(s3); } }此时 Qualifier 指定 s2但是属性名称指定 s3我们会发现最终找到的对象是 s2小结IoC1五大类注解和一个方法注解1. 类注解Controller、Service、Repository、Component、Configuration.2. 方法注解Bean.其中五大类注解分别代表不同的语义Controller控制层Service业务逻辑层Repository数据层Component组件层Configuration配置层类注解在代码上生成的对象只有一个多次获取得到的也只有一个在使用上可以理解为 Service、Repository、Component、Configuration 在功能上是可以替换的但是在语义上是不同的但是 Controller 不要与它们替换接收请求最外层必须使用 Controller否则会出现意想不到的错误~~方法注解使用的场景1.代码不在我们这里在其他人写的代码那我们想把这个对象交给 Spring 进行管理我们没有办法去加就可以通过 Bean2.对于一个类型需要创建多个对象的时候使用 Bean 注解2ApplicationContextSpring 的上下文对象可以理解为 Spring 的运行环境应用程序运行的过程中需要获取到的一些资源都来自 ApplicationContext这是一个很大的东西比如放了 JDK 的版本、环境变量、应用程序对象……可以通过 ApplicationContext 来获取对象其中一种方式就是 getBean这个方法来自 Bean工厂3Bean 的名称1.Bean Name 默认为类名的小驼峰2.如果类名前两位为大写BeanName 为类名也可以通过注解的 value 属性来修改4Bean1.BeanName 为方法名2.也可以通过 name 属性来指定 BeanNameDI1三种注入属性注入、构造方法注入、Setter 注入属性注入直接在属性上加上 Autowired它会根据类型然后去容器中查找并且赋值构造方法注入在构造方法上加上 Autowired如果只有一个构造方法Autowired 可以省略掉如果有多个需要添加上 Autowired 注解来指明到底使用哪个Setter 注入在 set 方法上添加 Autowired 注解2优缺点了解一下即可3Autowired 存在的问题Autowired 是根据类型查找的当同一个类型有多个 Bean 的时候使用 Autowired 会出现问题解决方式三种Primary指定默认的 bean如果有多个就会去找这个Qualifier指定 bean 名称Resource指定 bean 名称5.练习通过上面的学习, 我们把前面的图书管理系统代码进行调整Service层的注解, 改成 ServiceDao层的注解, 改成 Repository重新运行代码, 验证程序访问正常6.总结6.1 SpringSpring Boot 和 Spring MVC 的关系以及区别Spring:简单来说, Spring 是一个开发应用框架什么样的框架呢有这么几个标签轻量级、一站式、模块化其目的是用于简化企业级应用程序开发.Spring的主要功能: 管理对象IoC以及对象之间的依赖关系DI, 面向切面编程还没学, 数据库事务管理还没学, 数据访问, web框架支持等.但是Spring具备高度可开放性, 并不强制依赖Spring, 开发者可以自由选择Spring的部分或者全部, Spring可以无缝继承第三方框架, 比如数据访问框架(Hibernate 、JPA), web框架(如Struts、JSF)这是 Spring 相关的所以 IoC 和 DI 都是 Spring 提供的功能对对象管理而上面的这些就是 SpringBoot 相关的SpringBoot 主要是基于 Spring 给我们进行一些二次开发就像上次说的 12306 一样Spring类似于火车、高铁Spring Boot类似于 12306基于火车的基础上提供一些功能不局限于火车~~比如已经帮我们集成了 tomcat这就不需要我们自己安装了Spring MVC类似火车站火车票代售点提供一些对外访问的功能比如像 RequestMapping就来自于 SpringMVCSpring MVC:Spring MVC是Spring的一个子框架, Spring诞生之后, 大家觉得很好用, 于是按照MVC 模式设计了一个 MVC框架(一些用Spring 解耦的组件), 主要用于开发WEB应用和网络接口所以,Spring MVC 是一个Web框架.Spring MVC基于Spring进行开发的, 天生的与Spring框架集成. 可以让我们更简洁的进行Web层开发, 支持灵活的 URL 到页面控制器的映射, 提供了强大的约定大于配置的契约式编程支持, 非常容易与其他视图框架集成如 Velocity、FreeMarker等Spring Boot:Spring Boot是对Spring的一个封装, 为了简化Spring应用的开发而出现的中小型企业没有成本研究自己的框架, 使用Spring Boot 可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发而无需过多关注XML的配置和一些底层的实现.Spring Boot 是个脚手架, 插拔式搭建项目, 可以快速的集成其他框架进来.比如想使用SpringBoot开发Web项目, 只需要引入Spring MVC框架即可, Web开发的工作是SpringMVC完成的, 而不是SpringBoot, 想完成数据访问, 只需要引入Mybatis框架即可.Spring Boot只是辅助简化项目开发的, 让开发变得更加简单, 甚至不需要额外的web服务器, 直接生成jar包执行即可.最后一句话总结:Spring MVC和Spring Boot都属于SpringSpring MVC 是基于Spring的一个MVC 框架而Spring Boot 是基于Spring的一套快速开发整合包.比如我们的图书系统代码中整体框架是通过SpringBoot搭建的IoC, DI功能是Spring的提供的web相关功能是Spring MVC提供的这三者专注的领域不同解决的问题也不一样, 总的来说Spring 就像一个大家族有众多衍生产品, 但他们的基础都是Spring, 用一张图来表示他们三个的关系:6.2 bean 的命名1) 五大注解存储的bean① 前两位字母均为大写, bean名称为类名② 其他的为类名首字母小写③ 通过 value属性设置 Controller(value user)2) Bean 注解存储的bean① bean名称为方法名②通过name属性设置 Bean(name {u1,user1})6.3 常见面试题1) 三种注入方式的优缺点(参考上面课件内容)2) 常见注解有哪些? 分别是什么作用?web url映射: RequestMapping参数接收和接口响应: RequestParam, RequestBody, ResponseBodybean的存储: Controller, Service, Repository, Component, Configuration,Beanbean的获取: Autowired, Qualifier, Resource3) Autowired 和Resource 区别4) 说下你对Spring, SpringMVC, Springboot的理解(参考上面课件)