简介
Spring 春天,给软件行业带来了春天
2002,首次推出了框架interface21(spring前身)
2004,推出了spring框架
spring理念,使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的框架
优点
Spring是一个开源的免费框架
Spring是一个轻量级,非入侵式的框架
控制反转,面向切面编程
支持事务的处理,对框架整合的支持
总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
Spring的组成
拓展
在spring的官网的介绍,现代化的java开发, 就是基于Spring开发
SpringBoot
快速开发的脚手架,基于SpringBoot可以开发一个微服务
约定大于配置
学习SpringBoot,需要掌握Spring以及SpringMVC
SpringCloud
基于SpringBoot实现的
IOC理论推导
UserDao接口——UserDaoImpl实现类——UserService业务接口——UserServiceImpl业务实现类
下面是正常的项目目录结构
以前我们如果想要去改变这个接口,必须修改dao层的源码,如果有很多的类,就要一样的修改。但是现在我们利用接口的思想,只需要Service去调用即可。
package com.mmz.service;
import com.mmz.dao.UserDao;
import com.mmz.dao.UserDaoImpl;
/**
* @Classname UserServiceImpl
* @Description TODO
* @Date 2021/2/5 22:40
* @Created by mmz
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
相当于用一个set函数可以选择你到底使用什么dao层的类型。
在之前的业务中,用户的需求的变动会影响我们的代码,我们需要根据用户的需求去修改代码,如果程序的代码量十分庞大,修改一次的成本会特别高。
我们用一个set接口实现,已经发生了革命性的变化,原来的程序主动创建对象,控制权在程序员手上。使用set注入,程序不再有主动性,而是变成了被动的接收对象
这种思想从本质上解决了问题,程序员不用在管理对象的创建了。
系统的耦合性大大降低,可以更加专注在业务上的实现,这是IOC的原型。
IOC的本质
解耦之后,用户想要去调用谁就使用谁
Ioc是Spring框架的核心内容,使用多种方式完美的实现了Ioc,可以使用xml配置,也可以使用注解,新版本的Spring也可以零配置实现Ioc
Spring容器在初始化的读取配置文件,根据配置文件或者元数据创建与组织对象存入容器,程序使用时在从Ioc容器中取出需要的对象。
HelloSpring
首先编写自己pojo的类,这里用了lombok插件
编写beans.xml文件
beans.xml模板xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
</beans>
创建bean
<bean id="hello" class="com.mmz.pojo.Hello">
<property name="name" value="Spring"></property>
</bean>
实例化容器
提供使用applicationContext,可以从外部资源中加载我们的元数据
直接调用getBeans直接获取到对象,参数为当时我们在xml中注册的id即可。
@Test
public void testOfApp(){
// 如果用xml去配置,必须使用这个实现类
// 获取spring的上下文对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
// 现在我们使用的对象都在spring中管理了,我们想要使用哪个对象直接从Spring中取出来即可。
Hello hello = (Hello)applicationContext.getBean("hello");
System.out.println(hello);
}
测试结果
传统的对象是程序本身控制创建,使用Spring之后,对象是由Spring创建的,
反转之后,程序不会主动的创建对象,而变成被动的接受对象
依赖注入:本质就是由set注入的
根据上面学到的ioc修改一下ioc本质的代码
创建beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<!--使用Spring来创建,在Spring中都叫做bean-->
<!--
id 相当于变量名
class new的对象
property 给对象中的属性设置一个值
-->
<bean id="mysqlImpl" class="com.mmz.dao.UserDaoMysqlImpl"></bean>
<bean id="oracleImpl" class="com.mmz.dao.UserDaoOracleImpl"></bean>
<bean id="UserServiceImpl" class="com.mmz.service.UserServiceImpl">
<!--ref引用spring容器中创建好的对象-->
<!--value基本引用类型-->
<property name="userDao" ref="mysqlImpl"></property>
</bean>
</beans>
测试类直接调用
import com.mmz.dao.UserDaoMysqlImpl;
import com.mmz.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Classname MyTest
* @Description TODO
* @Date 2021/2/5 22:41
* @Created by mmz
*/
public class MyTest {
public static void main(String[] args) {
// 用户实际调用的是业务层,dao层他们不需要接触
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl userServiceImpl = (UserServiceImpl)applicationContext.getBean("UserServiceImpl");
userServiceImpl.getUser();
}
}
IOC创建对象的方式
使用无参构造函数创建对象,默认
假设我们要使用有参构造创建对象
public User(String name){
this.name = name;
}
下标赋值
<!--第一种,下标赋值-->
<bean id="user" class="com.mmz.pojo.User">
<constructor-arg index="0" value="mmz"></constructor-arg>
</bean>
通过类型创建
<!--不建议使用 通过类型创建-->
<bean id="user" class="com.mmz.pojo.User">
<constructor-arg type="java.lang.String" value="mmz"></constructor-arg>
</bean>
使用参数名来构造
<!--使用参数名来构造-->
<bean id="user" class="com.mmz.pojo.User">
<constructor-arg name="name" value="mmz"></constructor-arg>
</bean>
总结
在配置文件中加载的时候,容器中管理的对象就已经初始化了。
Spring配置
别名
<alias name="user" alias="asdad"></alias>
就是在getBean的时候,可以用别名的id来替换
相当于用别名来获取Bean
Bean的配置
暂无
import
这个import,一般用于团队开发使用,可以将多个配置文件,导入合并为一个
在这个resources目录下面,可以创建多个beans.xml可以不叫这个名字,最后我们在多个beans.xml 可以配置各自的bean,最后用import到导入一个xml文件即可。
内容相同也会被合并。
DI 依赖注入
构造器注入
前面已经说过,constructor-arg
set方式注入
property
依赖:bean对象都依赖于容器
注入:bean对象中的所有属性由容器注入
一样
<property name="name" value="mmz"></property>
<property name="name">
<value>mmz</value>
</property>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<bean id="address" class="com.mmz.pojo.Address">
<property name="address" value="xixi"></property>
</bean>
<bean id="student" class="com.mmz.pojo.Student">
<!--第一种,普通的值注入,直接用name/value就可以了-->
<property name="name" value="mmz"></property>
<!-- <property name="name">-->
<!-- <value>mmz</value>-->
<!-- </property>-->
<!--第二种,bean注入,ref-->
<property name="address" ref="address"></property>
<!--第三种,数组注入-->
<property name="book">
<array>
<value>红楼梦</value>
<value>水浒传</value>
<value>三国演义</value>
<value>西游记</value>
</array>
</property>
<!--第四种,list注入-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>敲代码</value>
<value>看电影</value>
</list>
</property>
<!--第五种,map-->
<property name="card">
<map>
<entry key="身份证" value="123456"></entry>
<entry key="银行卡" value="654321"></entry>
</map>
</property>
<!--第六种,set-->
<property name="games">
<set>
<value>英雄联盟</value>
<value>炉石传说</value>
</set>
</property>
<!--第七种,null-->
<property name="wife">
<null></null>
</property>
<!--第八种,info-->
<property name="info">
<props>
<prop key="学号">2018544031</prop>
<prop key="姓名">mmz</prop>
</props>
</property>
</bean>
</beans>
拓展方式注入
Bean的作用域
六种
重点掌握单例和多例
单例
就只有一个实例,默认为单例
多例 原型模式
在bean标签中的修改
每次从容器中get一个bean,都会产生一个新的对象
其余的
request session application
在web开发情况中使用