建设智能家居网站SWOT分析,注释网站开发,百度搜索不到网站,网站页面架构本篇博客主要讲解 扫描路径 DI详解#xff1a;三种注入方式及优缺点 经典面试题 总结 五、环境扫描路径
虽然我们没有告诉Spring扫描路径是什么#xff0c;但是有一些注解已经告诉Spring扫描路径是什么了
如启动类注解SpringBootApplication。
里面有一个注解是componentS… 本篇博客主要讲解 扫描路径 DI详解三种注入方式及优缺点 经典面试题 总结 五、环境扫描路径
虽然我们没有告诉Spring扫描路径是什么但是有一些注解已经告诉Spring扫描路径是什么了
如启动类注解SpringBootApplication。
里面有一个注解是componentScan这个注解就是扫描路径注解。 默认扫描路径 默认为启动类所在的路径 被componentScan标识的当前类所在的路径。 而启动类SpringBootApplication包含了componentScan。因此也是被SpringBootApplication标识的类。 注 这五大注解必须在Spring的扫描路径下才会生效。 package com.qiyangyang.iocdome; 因此 我们这个项目Spring的扫描路径是com.qiyangyang.iocdome这个路径。 因此当我们移动IocDomeApplication这个类到不同的文件中。Spring的默认扫描路径就会发生改变。 我们通常把启动类放在最外层Controller、Service...的上一层。这样就可以扫描到使用IoC的类了。如果非要放在别的地方。你希望它扫描哪些路径你也可以指定。 指定扫描路径 我们也可以通过 ComponentScan注解 指定扫描路径 指定方法在启动类上面加上如下注解 扫描路径的起始文件地址是java文件的下一级目录。 ComponentScan“扫描路径” eg ComponentScan“com.qiyangyang.iocdome” 如果什么都没加默认为被该注解标识的所在的类的路径。 六、依赖注入DI详解 DIDependency-Injection依赖注入 容器在运行期间,动态的为应用程序提供运行时所依赖的资源称之为依赖注入。 程序运⾏时需要某个资源此时容器就为其提供这个资源. 从这点来看, 依赖注⼊DI和控制反转IoC是从不同的⻆度的描述的同⼀件事情就是指通过 引入IoC容器利用依赖关系注入的方式实现对象之间的解耦。 依赖注入是⼀个过程是指IoC容器在创建Bean时,去提供运行时所依赖的资源而资源指的就是对象. 在下面程序案例中
我们使用了 Autowired 这个注解完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中.。在一些文章中。依赖注⼊也被称之为对象注入,属性装配,
具体含义需要结合文章的上下文来理解
关于依赖注入,Spring也给我们提供了三种方式:
6.1 Autowired属性注入(Field-Injection)
这个方法我们在上一篇文章使用过。这是重述一遍
RestController
RequestMapping(/book)
public class BookController {
//属性注入Autowiredprivate BookService bookService;
} 由于BookService类已经被Service注解过。因此已经将BookService类的对象存入了Spring容器 在我们后续使用它的对象的时候。不需要我们自己new这个对象。而是可以通过如上定义一个BookService属性。通过Autowired注解将这个对象取出。这样后续就可以直接用这个对象 6.2 构造方法注入(Constructor-Injection)
注当我们手动加上构造函数之后。一定要养成习惯把默认无参构造方法写上
当有单个构造函数
Spring知道使用哪个。因此会正常运行。 RestController
RequestMapping(/book)
public class BookController {
//构造方法注入private BookService bookService;public BookController(BookService bookService){this.bookService bookService;}
Controller(bean) //创建对象 //括号中是对bean进行重命名 如果没有指定名称spring帮我们指定
public class UserController {private UserService userService;private UserRepository userRepository;public UserController(UserService userService, UserRepository userRepository) {this.userService userService;this.userRepository userRepository;}public void say(){userService.say();userRepository.say();System.out.println(Hi Controller!!!);}
} 当有多个构造函数
Controller(bean) //创建对象 //括号中是对bean进行重命名 如果没有指定名称spring帮我们指定
public class UserController {private UserService userService;private UserRepository userRepository;public UserController(){}public UserController(UserRepository userRepository) {this.userRepository userRepository;}public UserController(UserService userService, UserRepository userRepository) {this.userService userService;this.userRepository userRepository;}public void say(){userService.say();userRepository.say();System.out.println(Hi Controller!!!);}
} 优先使用默认无参构造函数。如果没有。就会报错。 Autowired 指定使用某个构造函数 Autowiredpublic UserController(UserService userService, UserRepository userRepository) {this.userService userService;this.userRepository userRepository;} 6.3 Setter 注入(SetterInjection) 也需要搭配AutoWired注解才可以正常注入。
private UserService userService;
private UserRepository userRepository;
Autowired
public void setUserService(UserService userService) {this.userService userService;
}
Autowired
public void setUserRepository(UserRepository userRepository) {this.userRepository userRepository;
} 6.3三种依赖注入优缺点
属性注入Spring最不推荐但没关系 优点: 简介使用方便 缺点: 1.只能用于 IoC 容器。因为它是Spring提供的。 若不是 IoC 容器不可用且只有在使用的时候才会出现 NPE空指针异常 2.不能注入一个final修饰的属性。 构造方法注入Spring4.x推荐
我们可以点进Autowired注解。再点击目录。看到我们现在使用的Spring版本。 优点 1.可以注入final修饰的属性 注final修饰的属性有一个要求需要满足下列任意条件 ①声明时要完成初始化 ②在构造函数中进项赋值。 2.注入的对象不会被修改 3.依赖对象在使用前一定会被完全初始化因为依赖是在类在构造方法中执行的。而构造方法是在类加载阶段就会执行的方法。 4.通用性好。构造方法是JDK支持的所以更换任何框架他都适用。 缺点 1.注入多个对象时代码会比较繁琐。 Setter注入Spring3.x推荐 优点 方便在类实例之后重新对该对象进行配置或注入 缺点 1.不能注入一个final修饰的属性 2.注入对象可能会被改变。因为setter方法可能会被多次调用。就有被修改的风险。 6.4AutoWired存在的问题
当同一类型存在多个Bean时。使用Autowired会存在问题
Configuration
public class BeanConfig {Beanpublic UserInfo userInfo1(){UserInfo userInfo new UserInfo();userInfo.setId(120);userInfo.setName(张三);userInfo.setAge(18);return userInfo;}Beanpublic UserInfo userInfo2(){UserInfo userInfo2 new UserInfo();userInfo2.setId(121);userInfo2.setName(李四);userInfo2.setAge(28);return userInfo2;}
} 报错的原因是非唯一Bean对象。
Spring提供了一下几种解决方案。
Primary
在构造多个对象时
使用Primary注解当存在多个相同类型的Bean注入时加上Primary注解来确定默认的实现。
Configuration
public class BeanConfig {PrimaryBeanpublic UserInfo userInfo1(){UserInfo userInfo new UserInfo();userInfo.setId(120);userInfo.setName(张三);userInfo.setAge(18);return userInfo;}Beanpublic UserInfo userInfo2(){UserInfo userInfo2 new UserInfo();userInfo2.setId(121);userInfo2.setName(李四);userInfo2.setAge(28);return userInfo2;}
} 这样就不会报错了。也就是默认使用张三这个对象进行使用。 Qualifier
使用Qualifier注解在注入时。指定当前要注入的bean对象。在Qualifier的value属性中指定注入的bean 的名称。
Qualifier注解不能单独使用必须配合Autowired使用 Qualifier(userInfo2)//指定bean的名称Autowiredprivate UserInfo userInfo;public void say(){System.out.println(Hi Controller!!!);userService.say();System.out.println(userInfo);}
Resource
使用Resource注解是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。
不用Autowirede注解配合使用。 Resource(nameuserInfo2)private UserInfo userInfo;public void say(){System.out.println(Hi Controller!!!);userService.say();System.out.println(userInfo);} 常见面试题:
1.Autowird与Resource的区别 • Autowired是spring框架提供的注解Resource是JDK提供的注解 • Autowired 默认是按照类型注入Resource是按照名称注入相比于Autowired来说 Resource支持更多的参数设置例如 name 设置根据名称获取 Bean。 2.SpringSpringBootSpringMVC之间的区别和联系你是如何理解的? 我的理解 1.Spring很早 简单来说Spring是一个轻量级、一站式、模块化的开发应用框架。主要用于简化企业级应用程序开发。 Spring的主要功能管理对象以及对象之间的依赖关系。面向切面编程、数据库事务管理、数据访问、web框架支持等。 Spring这里指Spring-core。Spring家族都具有高度可开放性具备高度可开放性。并不强制依赖Spring开发者可以自由选择Spring的部分或者全部Spring可以无缝集成第三方框架。比如数据访问框架Hibernate、JPA、web框架如Struts、JSF。 在使用Spring时不强制使用Spring框架也可以使用第三方框架。 2.SpringBoot晚 是对Spring的一个封装为简化Spring应用的开发而出现的。中小型企业。没有成本研究自己的框架使用SpringBoot可以快速的搭建框架降低开发成本。让开发人员更加专注于Spring应用的开发。而无需过多关注xml的配置和一些底层实现。 SpringBoot是一个手脚架插拔式搭建项目可以快速的集成其他框架进来。 比如想使用SpringBoot开发Web项目只需要引入SpringMVC即可。Web开发的工作是SpringMVC完成的。而不是SpringBoot。想完成数据访问只需要引入Mybatis框架即可。 SpringBoot只是辅助简化项目开发的让开发变得更简单甚至不需要额外的web服务器直接生产jar包执行即可。 使我们在创建项目的时候可以直接添加一些依赖。并且内置web服务器、提供许多注解方便我们书写代码。对项目进行更多的监控指标更好的了解项目的运行情况。简化我们的开发。 3.SpringMVC早 是一个Spring家族的子框架。是针对Web开发和网络接口的一种MVC的思想的实现。也被称作Spring Web MVCSpring Web。 在创建项目时我们添加的依赖Spring Web实际上引的就是SpringMVC。可以认为Spring给我们提供的Web功能就叫做SpringMVC。 我们现在认为SpringMVC就是SpringWeb。主要进行Web开发网站开发。 最后一句总结Spring MVC和Spring Boot都属于Spring。Spring MVC是基于Spring的一个MVC框架。而Spring Boot是基于Spring的一套快速开发整合包 比如我们的图书系统代码中 整体框架是通过SpringBoot搭建的 IoC、DI功能是Spring的提供的, web相关功能是Spring MVC提供的。 这三者专注的领域不同解决的问题也不⼀样,总的来说Spring就像一个大家族有众多衍生产 品,但他们的基础都是Spring,用一张图来表他们三个的关系: 假如把Spring看作火车。而做项目相当于坐火车 但是它买票不方便。 因此就可以把SpringBoot看作是12306。而12306不仅可以订票还可以订酒店。打的等等。让我们坐火车做项目更加的方便 而SpringMVC 可以认为是火车里面提供的一些功能。比如买票改签插座等等。注解/CookieSession 3.ApplicationContext VS BeanFactory 1.继承关系和功能方面来说 Spring 容器有两个顶级的接口BeanFactory和 ApplicationContext。其中BeanFactory提供了基础的访问容器的能力而ApplicationContext 属于BeanFactory的⼦类它除了继承了BeanFactory的所有功能之外 它还拥有独特的特性还添加了对国际化支持、资源访问支持、以及事件传播等方面的支持. 2.从性能方面来说 ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象而BeanFactory 是需要那个才去加载那个因此更加轻量. (空间换时间) 4.三种依赖注入优缺点
属性注入Spring最不推荐但没关系 优点: 简介使用方便 缺点: 1.只能用于 IoC 容器。因为它是Spring提供的。 若不是 IoC 容器不可用且只有在使用的时候才会出现 NPE空指针异常 2.不能注入一个final修饰的属性。 构造方法注入Spring4.x推荐
我们可以点进Autowired注解。再点击目录。看到我们现在使用的Spring版本。 优点 1.可以注入final修饰的属性 注final修饰的属性有一个要求需要满足下列任意条件 ①声明时要完成初始化 ②在构造函数中进项赋值。 2.注入的对象不会被修改 3.依赖对象在使用前一定会被完全初始化因为依赖是在类在构造方法中执行的。而构造方法是在类加载阶段就会执行的方法。 4.通用性好。构造方法是JDK支持的所以更换任何框架他都适用。 缺点 1.注入多个对象时代码会比较繁琐。 Setter注入Spring3.x推荐 优点 方便在类实例之后重新对该对象进行配置或注入 缺点 1.不能注入一个final修饰的属性 2.注入对象可能会被改变。因为setter方法可能会被多次调用。就有被修改的风险。 5.常见注解有哪些?分别是什么作用?
1. web url映射: RequestMapping
2.参数接收和接口响应:RequestParam,RequestBody,ResponseBody
3.bean的存储:Controller,Service,Repository,Component,Configuration,Bean
4.bean的获取: Autowired, Qualifier, Resource
5.多个bean的默认指定Primary
6.Spring两大核心思想IOC和AOP 待续 总结
告诉spring管理BeanBean的存储
1.类注解五大注解ControllerComponentConfigurationServiceRepository
2.方法注解Bean
Bean的名称
1.五大注解
类名首字母小写如果前两位字母均为大写则为原类名也可以指定Bean的名称
指定方法Controller“beanName”
2.bean
默认名称是方法名也可以指定名称Bean“beanName”
使用场景
1.五大注解 自己开发的程序
2.Bean
①存储第三方的对象代码不在自己的项目中
②一个类型需要创建多个对象时
获取bean三种扫描路径的方式
通过Spring运行环境的Spring上下文
ApplicationContext context SpringApplication.run(IocDomeApplication.class, args);
获取Bean的功能是BeanFeactory提供的
三种方式
1.通过类型
UserController bean1 context.getBean(UserController.class);
bean1.say();2.通过bean名称
UserService userService (UserService) context.getBean(userService);
userService.say();
3.通过bean名称类型
UserComponent userComponent context.getBean(userComponent, UserComponent.class);
userComponent.say();
扫描路径
默认扫描路径启动类所在的路径
指定扫描路径 在启动类上面加上如下注解
ComponentScan“扫描路径”