一.spring框架
-
spring介绍
spring框架:spring是一个非常活跃的开源框架。基于IOC和AOP来架构多层javaee系统,以帮组分离项目组件之间的的依赖关系(解藕)
-
spring功能
spring ioc 能够帮助我们根据配置文件创建及组装对象之间的依赖关系
spring aop能够帮助我们无耦合的实现日志记录,性能统计,安全控制
spring 能够非常简单的帮助我们管理数据库事务
spring提供了与第三方数据访问框架的无缝连接。比如hibernate,mybatis,而且自己也提供了一套jdbc模版用来数据库的访问
spring还提供了与第三方web框架的无缝连接,比如structs,并且自己也提供了一套springMVC框架,来方便web层的搭建
-
spring组成
core 核心模块
- spring-core:依赖注入IOC与DI的最基本实现
- spring-beans:Bean工厂与bean的装配
- spring-context:spring的context上下文 即IOC容器
- spring-context-support:spring-context的扩展支持,用于MVC方面
- spring-expression:spring表达式语言
二.IOC与DI
依赖注入或控制反转 的定义中,调用者不负责被调用者的实例创建工作,该工作由Spring框架中的容器来负责,它通过开发者的配置来判断实例类型,创建后再注入调用者。由于Spring容器负责被调用者实例,实例创建后又负责将该实例注入调用者,因此称为 依赖注入。而被调用者的实例创建工作不再由调用者来创建而是有Spring来创建,控制权由应用代码转移到了外部容器,控制权放生了反转,因此称为 控制反转
-
IOC-控制反转
IOC 是Inverse of Control 的简写,意思是控制权反转,是降低对象之间的耦合关系的设计思想
通过IOC,开发人员不需要关心对象的创建过程,交给spring容器来完成,具体的过程是:
程序读取spring的配置文件,获取需要创建的bean对象 ,通过反射机制创建对象的实例
缺点: 对象是通过反射机制实例化出来的,因此对系统的性能有一定影响,将对象的创建权反转给Spring容器
-
DI-依赖注入
Dependency injection,说的是创建对象实例的同时,同时为这个对象注入他所依赖的属性。相当于把每个bean与bean之间的关系交给容器管理。而这个容器就是spring
例如 我们通常在Service 层注入他所依赖的Dao层的实例; 在 Controller 层注入 Service层的实例
三.入门程序
-
第一个spring程序
-
创建项目,配置maven环境,配置spring所需jar包
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> </dependencies>
-
创建一个类
@Setter @Getter public class Drink { private String name; private Integer price; public Drink(){ System.out.println("给你一杯果汁"); } }
-
在reource文件夹下创建一个 applicationContext.xml 的spring配置文件
<?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"> <!-- 创建一个 Drink类 --> <bean id="drink" class="com.zhj.domain.Drink"/> </beans>
-
测试
public class MyTest { @Test public void test1(){ // 创建一个ioc容器 ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Drink drink = (Drink) app.getBean("drink"); // 从容器中获取对象 } }
-
四.bean标签的使用
<!-- 创建一个 Drink类 -->
<bean id="drinkid" name="drinkname" class="com.zhj.domain.Drink"/>
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("----------");
Drink drink1 = (Drink) app.getBean("drinkid"); // 直接从工厂中获取
Drink drink2 = (Drink) app.getBean("drinkname");
System.out.println(drink1);
System.out.println(drink2);
执行结果:
给你一杯果汁
----------
com.zhj.domain.Drink@6b9651f3
com.zhj.domain.Drink@6b9651f3
-
id 与 name 属性
使用任意一个即可
-
单例模式
spring 是默认使用单例模式的,默认是不是懒加载
默认:可以看出两次打印的内存地址一样
懒加载(按需加载) :
默认不是懒加载 : 在getBean之前,也就是说在获取app配置文件的时候,就已经被创建
如何设置: 配置属性 lazy-init=“true”
-
多例模式
scope 属性
属性值:
singleton:单例,默认
prototype:多例
-
初始化与销毁方法
初始化方法:
属性 init-method = “”
设置之后 ,在构造方法之后 ,自动调用
销毁方法:
属性 destroy-method = “”
销毁对象之前,自动调用
<bean id="drinkid" name="drinkname" lazy-init="true" init-method="init" destroy-method="destroy" class="com.zhj.domain.Drink"/>
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("----------"); Drink drink1 = (Drink) app.getBean("drinkid"); // 直接从工厂中获取 Drink drink2 = (Drink) app.getBean("drinkname"); System.out.println(drink1); System.out.println(drink2); app.registerShutdownHook(); // 销毁对象
五.创建对象的三种方式
-
通过构造函数创建(默认调用的事无参构造方法)
<bean id="drink" class="com.zhj.domain.Drink"/>
-
通过静态工厂创建
在整合第三方框架的时候,需要创建第三方框架中类的对象,而这个类的构造方法并没有提供,只提供了静态工厂以及工厂中创建这个对象的方法,这个时候,只能利用静态工厂来创建对象
public class StaticFactory { public static Drink getDrink(){ return new Drink(); } }
<!-- 创建一个 Drink类 --> <bean id="createDrinkByStaticFactory" class="com.zhj.factory.StaticFactory" factory-method="getDrink"/>
测试
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Drink drink = (Drink) app.getBean("createDrinkByStaticFactory");
-
通过非静态工厂创建
在整个第三方框架的时候,需要创建第三方框架中类的对象,而这个类的构造方法并没有提供,只提供了工厂及工厂中创建这个对象的方法,这个时候只能利用这个工厂来创建对象了
public class Factory { public Drink getDrink(){ return new Drink(); } }
<bean id="createDrinkByFactory" class="com.zhj.factory.Factory" /> <bean id="getDrink" factory-bean="createDrinkByFactory" factory-method="getDrink"/>
@Test public void test1(){ ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("---"); Drink drink = (Drink) app.getBean("getDrink"); }
注意: 在applicationContext中,类 只要没有设置为 延迟加载 或 多例模式,
在创建 ClassPathXmlApplicationContext 对象的时候,都会默认值执行一遍 所有类的 构造方法