Spring-core

简介

为什么要学习框架

框架相当于从小作坊到工厂的升级, 小作坊什么都要自己做, 工厂是组件式装配, 特点是高效.就好比开个餐厅,自己弄的话很麻烦, 需要考虑很多, 框架是加盟, 全部都由别人弄好, 自己经营
框架更加易用,简单且高效

优点

无需配置Tomcat, 点击运行即可运行项目. 因为SpringBoot内置了Web容器, 可以直接运行
快速添加外部jar包
快速发布项目, 使用java -jar xxx即可发布
对象自动装配

Servlet和Spring对比

Servlet: 创建项目-补充目录-引入依赖-写代码-配置Tomcat-运行测试
Spring: 创建项目-写代码-运行测试
Servlet用context path来区分业务, Spring用端口号来区分
对于新增一个需求, Servlet新增一个类, Spring是新增一个方法. 更改请求类型, Servlet要把doGet改成doPost, 而Spring什么都不用做

Spring是个包含众多工具的IoC容器

容器

容器一般是指装东西的物体. 比如水杯装水,学校装老师学生, Tomcat装Web服务.而Spring就是存放对象的容器

IoC(Inversion of Control)

IoC是指控制反转, 是说控制权的反转.
例如class A里面实例化了一个MessageDao的对象, 那么这个对象的生命周期由对象A来管理. 而现在用Spring来管理对象的生命周期

传统思想开发&IoC

要制造一个车, 需要依赖车架,车架依赖底盘,底盘依赖轮胎.如果在构造方法里实例化依赖的对象, 如果发生了一点变化, 代码改动非常大, 因为互相嵌套. 用IoC则不会互相嵌套太多,只需要加属性和构造方法即可,不用担心嵌套.
Spring-core_第1张图片Spring-core_第2张图片
IoC的优势就是程序解耦
image.png

DI:依赖注入

所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容 器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦.
IoC是一种思想, DI是实现

Spring的创建

过程

①创建一个空的maven项目
②引入Spring依赖

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.2.3.RELEASE</version>
</dependency>
③添加一个启动类

存对象

resources文件夹下创建一个.xml文件, 名字无所谓,可以起spring-config.xml,里面写上

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>
要存对象的话, 在里面写上如下内容,下面是创建两个对象`user1`和`user2`,类是`example.User`. 类要加上路径,方便区分
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user1" class="example1.User"></bean>
    <bean id="user2" class="example1.User"></bean>
</beans>

获取Spring上下文对象

①得到Spring上下文对象,因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下⽂
②通过 Spring 上下⽂,获取某⼀个指定的 Bean 对象
③使⽤ Bean 对象

使用ApplicationContext获取对象

ApplicationContext context = new 
    ClassPathXmlApplicationContext("spring-config.xml");

使用BeanFactory获取对象

BeanFactory factory = new 
    XmlBeanFactory(new ClassPathResource("spring-config.xml"));

获取Bean对象

.getBean(id,class)
①根据xml里面对象的id来获取对象: 每个对象的id是唯一的
User user1 = (User) context.getBean("user1");
②根据类来获取: 前提是xml里那个类只有一个对象, 好处是不需要类型转换
User user2 = context.getBean(User.class);
③使用id和class一起来获取: 不用类型转换
User user3 = context.getBean("user1",User.class);
注意点:
不论我们拿了多少次, 或者使用哪和方式取对象, 获取的都是同一个对象

BeanFactory&Applicationcontext区别

共同点:
都是获取spring bean的
不同点:
①Applicationcontext是BeanFactory的子类
父类的功能子类都有(国际化,环境,资源文件管理等…)
②性能
Applicationcontext提前把bean全部加载完,使用时候直接取出来(空间换时间)
BeanFactory是懒加载的模式,使用的时候采取创建(时间换空间)

更简单的存对象

过程

①配置扫描路径:首先在xml文件里加上:

引号里写的是需要扫描的路径
②加上注解, 还可以自定义名称
③使用对象

五大类注解

一般情况是新建一个包专门用来被扫描, 包的子目录有5个,分别是五大注解的名字:
Controller(控制器存储),Service(服务存储),Repository(仓库存储),Component(组件存储),Configuration(配置存储)
@Controller:表示的是业务逻辑层. 控制器,通常是指程序的入口,比如参数校验,参数类型转换...前置处理工作
@Servie:服务层.一般写业务代码,服务编排
@Repository:持久层.通常是指DB操作相关的代码
@Configuration:配置层
使用类对象的时候:如果没有重命名, 使用类名的首字母小写即可选中使用哪个类.当类名前两个字母都是大写的时候,首字母小写就不行了,要用原名

使用方法(都一样)

注解存储对象:

@Controller // 将对象存储到 Spring 中
public class UserController {
	public void sayHi(String name) {
	System.out.println("Hi," + name);
	}
}

使用对象:

public class Application {
    public static void main(String[] args) {
    	// 1.得到 spring 上下⽂
    	ApplicationContext context = 
            new ClassPathXmlApplicationContext("spring-config.xml");
    	// 2.得到 bean
    	UserController userController = 
            (UserController) context.getBean("userController");
    	// 3.调⽤ bean ⽅法
    	userController.sayHi("Bit");
    }
}

重命名

注解后面加上名字即可, 例如:
@Controller("usercontroller")

方法注解@Bean

使用

@Bean需要搭配五大注解使用

@Component
public class Users {
	@Bean
	public User user1() {
		User user = new User();
		user.setId(1);
		user.setName("Java");
		return user;
	}
}

@Bean对应生产的bean名称是方法名

public class Application {
	public static void main(String[] args) {
		ApplicationContext context =
		new ClassPathXmlApplicationContext("spring-config.xml");
		User user = (User) context.getBean("user1");
		System.out.println(user.toString());
	}
}

重命名

①重命名的name是一个数组,一个bean可以有多个名字, 例如:
@Bean(name={"u1","u2"})
②name={}可以省略, 例如:
@Bean({"u1","u2"})

为对象设定属性值

**设定属性的时候必须要保证有对应的构造函数,不然会报错**

方法注解传参

如果传的参数类型只有一个对象,那么就自动用那个对象,尽管名字不匹配
如果传的参数类型有多个对象,那么按照名字匹配,名字配不上就报错
Spring-core_第3张图片

xml文件传参

用xml不加注解(虽然加了也不会报错. 注解和xml的id重复没事,但id和id之间绝对不能重复).

<bean id="userController" class="com.controller.UserController">
  <constructor-arg name="name" value="zhangsan">constructor-arg>
bean>

注意事项

如果传参的时候,传入的参数类型是引用数据类型, 那么xml的value="xxx"要改成ref="xxx"

<bean id="userController" class="com.controller.UserController">
  <constructor-arg name="name" value="zhangsan">constructor-arg>
bean>

对象装配(属性注入/依赖注入)

上面的方法太麻烦

属性注入@Autowired

通过加@Autowired注解注入: 不用写xml,不用写构造函数
UserController依赖UserService, 给UserService加注解. 虽然官方不推荐使用, 但是实际开发中使用最多
Spring-core_第4张图片
这里的注入也是按照下面的方式匹配
Spring-core_第5张图片
特点:
Spring-core_第6张图片

Setter方法注入

用Setter方法给us设置属性值, 然后给Setter方法加上注解@Autowired
Spring-core_第7张图片
特点:
Spring-core_第8张图片

构造函数注入

一个类默认有一个无参的构造函数. 当我们写了有参的构造函数, 就没有这个默认的无参构造函数了
创建对象需要调用构造函数
当前存在多个构造函数, spring就不知道用哪个构造函数, 所以会报错, 我们需要告诉Spring,使用哪个构造函数. 给要用的构造函数加注解既可以告诉spring
Spring-core_第9张图片
特点:
Spring-core_第10张图片

@Resource注入(JDK提供)

@Resource可以改名字:@Resource(name="user")
@Autowired不能这么改,改的话要再加一个@Qualifier(value="user")来重命名Spring-core_第11张图片

Bean作用域

singleton 单例作用域

Spring-core_第12张图片
无状态是指对象的状态不需要更新, 属性值都不会变化
ScopeController将user名字改成"张三获取的User", 之后scopeController2调用sayHi方法,结果也是"张三获取的User". 因为是单例模式, 对象都是同一个, 名字被改了其他调用者也用的是被改的名字
Spring-core_第13张图片
Spring-core_第14张图片
Spring-core_第15张图片
可以在@Bean注解前加一个@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)可以简写成@Scope("prototype")让他变成多例模式.

prototype 原型作用域(多例作用域)

Spring-core_第16张图片

request 请求作用域

Spring-core_第17张图片

session 会话作用域

Spring-core_第18张图片

application 全局作用域

Spring-core_第19张图片

websocket HTTPWebSocket作用域

Spring-core_第20张图片

Bean的生命周期

Spring-core_第21张图片

实例化Bean

为Bean分配内存空间(不等于初始化).

设置属性

Bean的注入和装配

Bean初始化

Spring-core_第22张图片

使用Bean

销毁Bean

你可能感兴趣的:(JavaEE,java,spring)