在五个月之前,对Spring进行了学习,当时还是一知半解,无法把之前的知识与该框架结合清除,导致感觉学习的非常之凌乱,现在重拾Spring,开始狠狠地学一崩子。
一、Spring
1.首先来区分一下SpringBoot 与 Servlet 之间的区别
(1)创建过程
servlet :流程复杂,容易出错。因为需要去仓库:https://mvnrepository.com/查找servlet 对应的版本和引用信息,添加到pom.xml;点击maven导入框架按钮,创建java源代码目录。
springboot:直接创建springboot项目,并勾选添加项目依赖即可
(2)编写代码
servlet:创建的类必须和功能一一对应,每一个类只能对应一个功能;且继承httpservlet 重写doGet/doPost方法;使用request来获取参数,设置返回的类型,编码格式,使用response对象返回结果。
springboot:可以使多个URL对应一个类;创建一个UserController类,在类名上加上注解@Controller /@RequestMapping("URL")
(3)运行项目
servlet:需要外置的Tomcat,社区版idea安装插件smarttomcat,下载并解压tomcat;配置idea中的smartomcat运行Tomcat指向本地Tomcat,运行项目
springboot:内置Tomcat,直接运行;注解@SpringBootApplication,当前类为springboot启动类。
(4)发布项目
servlet:使用maven打包,将打包的war/jar 上传服务器,在服务器上安装(下载并解压)tomcat,将war包放入webapps,启动tomcat,运行项目
springboot:maven打包,上传war/jia ,使用 java - jar xxx.jar 直接运行项目
因此对于servlet的缺点:
①添加外部Jar不方便,容易出错,比如添加了一个不匹配的jar版本
②运行和调试的时候,需要配置tomcat
③发布不方便,servlet项目必须依靠外置的Tomcat
④路由配置不方便,一个访问地址对应一个servlet
二、Spring的学习
1.spring 的定义
它是包含了众多工具方法的IOC容器
spring是一个IOC容器,对象的创建和销毁的权利都交给了spring来管理
它本身又具备了存储对象和获取对象的能力
2.什么是IOC
inversion of Control 控制反转,控制权交给了框架
优点:实现代码的解耦,对象Bean生命周期交给IOC框架来维护,作为程序员无需关注
spring IOC 最核心的功能:
1.将Bean对象存储到spring容器中
2.将Bean对象从spring中取出来
3.DI 依赖注入
IOC是一种实现的思想,而DI是实现该思想的一种方式
三、spring的创建和使用
1,创建spring项目
①创建一个maven项目
②添加spring框架支持(sping-context,spring-beans)
③添加启动类
2.存储Bean对象到容器spring中
①如果第一次添加,先在spring项目中添加配置文件,非第一次可省略
②先创建一个Bean对象
③在配置文件中将需要保存到spring中的bean对象进行注册
添加spring配置文件(如果第一次添加):
放在resource目录中,右键新增file,创建bean对象,
在java目录下,创建com.bean一个user类
如public class User{}
将bean对象通过配置文件,注册到spring中:
在上一步的xml中,加入<bean id="user" class="com.beans.User"></bean>
注意:id 可以不等于user类名
先得到spring上下文对象,再通过上下文提供的方法,获取需要使用的bean对象,方可使用
3.获取上下文对象
在main方法中:
//得到spring上下文对象
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//根据上下文对象提供的方法获取到Bean
User user=(User)context.getBean("user");
//使用bean对象
user.sayHi("张三");
注意:ApplicationContext VS BeanFactory
不同点: ①ApplicationContext是BeanFactory的子类
BeanFactory只提供了基础访问Bean的方法,
而ApplicationContext:还提供了其他方法,比如对国际化的支持,资源访问的支持,以及事件和传播等方面的支持
②从性能方面来说,BeanFactory是按需加载Bean,
ApplicationContext是饿汉模式,在创建时会将所有的Bean都加载起来,以备以后使用
4.关于getBean更多用法
//使用bean name获取bean
User user=(User)context.getBean("user")
//根据bean type
User user=context.getBean(User.class);
//根据name和类型
User user=context.getBean("user",User.class)
其中第二个写法更加简单,但如果同一个类型被注入到spring多个,就会报错
四、更简单读取和存储对象---使用注解
1,前置工作
配置扫描路径,更加简单存和去Bean的前置工作,在spring配置文件中设置bean扫描路径
<content: component-scan base-package="com.beans"></content-scan>
2.使用5大类注解
@Controller 控制器 前端参数效验
@Service 服务 数据组装和接口调用
@Component 组件 防止组件、工具
@Respository 仓库 数据持久层,DAO层,负责和数据库进行交互
@Configuration 配置
使用类注解,让代码可读性提高,让程序员直观判断当前类的用途
这五大类注解,都是基于@Component注解实现的
3.通过@Bean注解
①关于Bean的命名,使用小驼峰
因为在源码里,第一步判空,第二步,判断如果name的长度大于1且第二个字母大写且第一个字母大写,则返回原name
如果不是,则把name的第一个字母改为小写再返回
②使用方法注解@Bean
如果只是用一个@Bean注解是无法将对象存储到容器中,必须在使用一个类注解,获得Bean对象中,参数必须是方法名
③通过类名获取时,如果该类有两个方法都返回相同对象,会报错,必须唯一
④@Bean重命名
@Bean(name={"userinfo","user1"})
public User getUser1(){
return new User().setId(1);
}
注意:当设置了name属性,使用方法名获取就无效了
⑤@Bean将一个类型的对象注入多次的问题
①使用@Resource(value="user1") 设置name方式
②精确描述bean的名称
@Autowired
private User user1;
③@Autowired
@Qualifier(value="user1")
五、获取Bean对象
获取Bean对象也称对象装配,是把对象取出来放到某个类中,有时候也叫对象注入
之前是通过context.getBean()进行注入
1.属性注入--@Autowired
@Autowired
private UserService userservice;
2.构造方法注入
@Autowired
public UserController3(UserService userService){
// userService=new UserService(); 传统写法
this.userService=userService;
}
3.Setter注入
@Autowired
public void setUserService(UserService userService){
this.userServive=userService;
}
4.这三种注入有什么区别
属性注入、构造方法注入、set注入
1.属性注入
特点,写法简单,只适用于ioc容器
2.set注入
官方推荐使用的,问题通用性没有构造方法注入通用
3.构造方法注入
通用性较好,能确保在使用注入对象之前,此注入对象一定进行了初始化
@Resource
支持属性,setter注入,不支持构造方法注入
总结:
@Resource和@Autowired区别
1.@Resource 是JDK的,@Autowired 是spring框架提供的
2.@Autowired 支持属性注入,构造方法注入,setter注入
@Resource 支持属性,setter注入
3.@Resource 支持参数较多,比如name,type设置,
@Autowired 只支持required参数设置
六、Bean的作用域
1.Bean默认情况下,是单例状态
因此如果有两个用户一个对其进行修改,另外一个读,读到是修改之后的
2.Bean的作用域:Bean在spring整个框架中的某种行为
①singleton:单例模式
②prototype:多例模式,原型模式
③request:请求作用域,使用spring MVC
④session:会话作用域 spring MVC
⑤application:全局作用域
⑥websocket:HTTP WebSocket作用域(spring WebSocket)
设置Bean的作用域:
使用注解:@scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
单例作用域singleton VS 全局作用域 application
1.singleton 是 springcore的作用域,application是spring WEB 中的作用域
2.singleton 作用于IOC的容器,application作用于servlet容器
七、Bean的生命周期
1.实例化Bean 为Bean分配内存空间
2.设置属性(进行对象注入)
3.初始化
执行各种通知(Aware)
执行初始化前置方法
执行构造方法,两种方式,一种执行@PostConstruct,另一种是init-method,先执行注解,再执行xml
执行初始化的后置方法
4.使用Bean
5.销毁bean
@PreDestory
重写DisposableBean接口方法
destory-method
如果初始化在设置属性之前,有可能造成空指针异常