Spring架构开荒

IOC控制反转InversionofControl控制反转依赖注入1控制什么?控制对象的创建以及销毁2反转什么?将对象的控制权交给IOC容器举例说明:张三要回家对象:小明人车奔驰宝马Audi.javapublicclassAudipublicvoidstart()System.out.println("Audi.start");}publicvoidturnLeft()System.out.pri...

Spring架构开荒
IOC 控制反转

Inversion of Control
控制反转 依赖注入
1 控制什么?

控制对象的创建以及销毁

2 反转什么?

将对象的控制权交给IOC容器

举例说明:

张三要回家
对象:

  • 小明 人
  • 车 奔驰 宝马
    在这里插入图片描述
    Audi.java
public class Audi{public void start(){System.out.println("Audi.start");}public void turnLeft(){System.out.println("Audi.start");}public void trunRight(){System.out.println("Audi.start");}public void stop(){System.out.println("Audi.start");}}
传统方式

张三控制车辆的流程:
1 创建一辆车

Audi audi = new Audi();

2 控制车辆的启动 直行 左右转

audi.start();audi.turnLeft();audi.trunRight();turn.stop();

3 销毁车辆

java的jcc组织垃圾回收处理掉

张三的其他需求

比如看电影

public void goMovice(){public void start(){System.out.println("Audi.start");}public void stop(){System.out.println("Audi.start");}}

现在张三要换一辆Buick车

在Zhangsan.java当就需要全部更改
产生了高耦合性

改进方案 1

把车升级到张三的属性域里面
这样就降低了耦合度

public class ZhangSan { Buick car = new Buick(); public void goHome(){  car.start();  car.turnRight();  car.turnLeft();  car.stop(); }}
改进方案 2

接口Car

public interface Car { public void start(); public void turnLeft(); public void turnRight(); public void stop();}

奔驰车实现这个车的接口

public class Audi implements Car{ public void start(){  System.out.println("Audi.start"); }

在ZhangSan当中用构造方法传进去Car

private Car car; public ZhangSan(Car car){  this.car = car; }

到现在Car已经不用ZhangSan来创建了 由IOC来创建了

车辆的控制权完全交给了IOC

实现自己编写一个IOC的容器

在这里插入图片描述

约定
  • 所有的Bean的生命周期交由IOC容器管理
  • 所有被依赖的Bean通过构造方法执行注入
  • 被依赖的Bean需要优先创建(创建张三前先创建奥迪)

所有被依赖的Bean通过构造方法执行注入

 public HumanWithCar(Car car) {  this.car = car; } private Car car;

Class003Test.java//测试IOC容器

public class Class003Test { private IoCConteainer ioCConteainer = new IoCConteainer(); @Before//创建bean public void before(){  ioCConteainer.setBean(Audi.class, "Audi");  ioCConteainer.setBean(Buick.class, "Buick");  ioCConteainer.setBean(ZhangSan.class, "ZhangSan","Audi");  ioCConteainer.setBean(Lisi.class, "Lisi","Buick"); } @Test//使用bean public void test(){  Human ZhangSan = (Human) ioCConteainer.getBean("ZhangSan");  ZhangSan.goHome();  Human Lisi = (Human) ioCConteainer.getBean("Lisi");  Lisi.goHome(); }}
Spring IOC入门

1 创建一个javabean

public class Bean{public Bean(){System.out.println("Bean.bean");}}

2 在pom中加入spring的依赖

spring-corespring-context

3 在resources文件夹下建立一个spring.xml文件

//class = 1 中创建的Bean 并给一个唯一标示id<bena class = "bean" class="com.imooc.spring.ioc.class004.Bean">

//测试

public class Class004Test { @Test public void test(){  ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml);  Bean bean = context.getBean("bean",Bean.class);  System.out.println("bean = "bean); }}

在这里插入图片描述

实例化Bean方式
  • 构造方法实例化
  • 静态方法
  • 实例方法
构造方法实例化

1 创建Bean.java

public class Bean { public Bean(){  System.out.println("Bean.bean"); }}

2 在spring.xml中配置bean

<bean class = "com.spring.ioc.class05.Bean1" id = "bean1"/>

3 在class005Test.java中实例

public class class005Test { @Test public void test(){  //取上下文  ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");  //通过context get一个Bean  Bean bean = context.getBean("bean", Bean.class);  System.out.println("bean = "bean); }}
静态方法实例化

1 创建一个BeanFactory.java
通过BeanFactory的getBean方法实例化Bean

public class Bean2Factory { public static Bean2 getBean2(){  return new Bean2(); }}

2 spring.xml中进行配置

<bean class = "com.spring.ioc.Class05.Bean2Factroy" factory-method = "getBean2" id = "bean2"/>

3 Class005Test.java

Bean2 bean2 = context.getBean("bena2", Bean2.class);
实例方法实例化Bean

1 创建一个Bean3Factory.java
通过BeanFactory的getBean方法实例化Bean

public class Bean3Factory { public static Bean3 getBean3(){  return new Bean3(); }}

2 spring.xml中进行配置

 <bean class = "com.spring.ioc.Class05.Bean3" factory-bean = "bean3Factory" factory-method = "getBean3" id = "bean3"/>

3 Class005Test.java

  Bean3 bean3 = context.getBean("bean3",Bean3.class);  System.out.println("bean3 = "bean3);
给Bean取一个别名

1 name属性

<bean class = "myspring.Bean" name  ="bean1_1,bean1_2 " id = "bean1"/>

2 alias属性

 <alias name = "bean1" alias="bean1_3,bean1_4"/>

测试

Bean1 bean1_1 = context.getBean("bean1_1",Bean1.class);System.out.println("bean1_1 = "bean1_1);Bean1 bean1_2 = context.getBean("bean1_2",Bean1.class);System.out.println("bean1_2 = "bean1_2);

但是这些名字不同的都是同一个Bean
在这里插入图片描述

在这里插入图片描述

注入Bean的方式
  • 构造方法注入Bean
  • set方法注入Bean
  • 集合类Bean的型注入
    • List
    • Set
    • Map
    • Propertise
  • null值注入
  • 注入时创建内部Bean

前期准备
AnotherBean.java

public class AnotherBean { }

Bena.java

public class Bean { private AnotherBean anotherBean; private String string; public AnotherBean getAnotherBean() {  return anotherBean; } public void setAnotherBean(AnotherBean anotherBean) {  this.anotherBean = anotherBean; } public String getString() {  return string; } public void setString(String string) {  this.string = string; }}
构造方法注入Bean

在Bean.java中写入构造方法

 public Bean(AnotherBean anotherBean, String string) {  this.anotherBean = anotherBean;  this.string = string; }

spring.xml

//index:参数是构造方法中的第几个参数//name:当前参数的参数名字//type:参数的类型//value: 给参数赋值 适合简单的数据类型 string integer  double float//ref:复杂数据类型赋值对应anotherbean的id
 <bean class = "com.example.controller.Bean" id = "bean">  <constructor-arg index="0" name = "anotherBean" type="com.example.controller.AnotherBean" ref="anotherBean"/>  <constructor-arg index="1" name="string" type="java.lang.String" value="aaaaa"/> </bean>

在这里插入图片描述
简单写法

 <bean class="com.example.controller.AnotherBean" id = "bean"  c:anotherBean-ref="bean1" c:string="ccccc" p:anotherBean1-ref="bean1_1" P:string1="ddddd" /> <util:property name="anotherBean1" ref = "anotherBean"/> <util:property name = "String1" value="ddddd"/>

在这里插入图片描述

set方法注入Bean

在这里插入图片描述

集合类型的Bean的注入
  • list
  • set
  • map
  • propertise

List
spring.xml

 <util:property name = "stringList">  <list><value>aaaaa</value><value>ddddd</value>  </list> </util:property> <util:property>  <list><ref bean = "anotherBean"/><ref bean = "anotherBean"/>  </list> </util:property>
 <util:propertiy name="properties">  <prop key="aaaaa">bbbbb</prop> </util:propertiy>

class005Test.java

  Bean bean = context.getBean("bean",Bean.class);  System.out.println("bean.getStringList() = "bean.getSring());  System.out.println("bean.getProperties() = "bean.getProperties());

在这里插入图片描述
在这里插入图片描述

null注入

Bean.java

 public AnotherBean getAnotherBean2() {  return anotherBean2; } public void setAnotherBean2(AnotherBean anotherBean2) {  this.anotherBean2 = anotherBean2; } private AnotherBean anotherBean2;

spring.xml

 <util:properties name = "anotherBean2">  <null/> </util:properties>

class005Test.java

System.out.println("bean.getAnotherBean2()"bean.getAnotherBean2());

在这里插入图片描述

注入的时候创建内部Bean
 <util:properties>  <bean class = "com.example.controller.AnotherBean"/> </util:properties>

在这里插入图片描述

Bean的作用域的问题
  • Sinleton作用域

  • prototype作用域

  • Web环境作用域

    • requset
    • session
    • application
    • websocket
  • 自定义作用域

    • SimpleThreadScope作用域
Singleton作用域(单例模式)

在这里插入图片描述
右侧的Bean会通过Spring注入左侧三个Bean中 只会创建一个Bean

Bean.java

public class Bean { public Beanb getBeanb() {  return beanb; } public void setBeanb(Beanb beanb) {  this.beanb = beanb; } private Beanb beanb; @Override public String toString() {  return "Bean{""beanb="beanb'}'; }}

spring.xml

 <bean class = "com.example.controller.People.Beanb" id = "bean2"  scope="prototype"/> <bean class = "com.example.controller.People.Bean" id = "bean" scope="prototype">  <property name="beanb" ref="bean2"></property> </bean>
public class Class007Test { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Beanb bean2_1 = context.getBean("Beanb",Beanb.class); System.out.println("bean2_1 = "bean2_1); Beanb bean2_2 = context.getBean("bean2_2 = "bean2_2); System.out.println("bean2_2 = " bean2_2); bean bean1 = context.getBean("bean",Bean.class); System.out.println("bean = "bean);}

在这里插入图片描述
在这里插入图片描述

Prototype作用域(多例模式)

在这里插入图片描述

在这里插入图片描述

Web相关作用域
  • requset作用域
  • sessiong作用域
  • applicatiton作用域
  • websocker作用域(很少使用)

SpringWeb上下文环境

如果使用DispatcherServlet 不需要增加其他配置

在这里插入图片描述

web.xml
在这里插入图片描述
RequsetController.java
在这里插入图片描述
spring.xml

<bean class="com.spring.ioc.class08.RequestController"/><bean class="com.spring.ioc.class08.SessionController"/><bean class="com.spring.ioc.class08.ApplicationController"/>

在这里插入图片描述
每次刷新@contraller不变

<bean class="com.spring.ioc.class08.RequestController" scope = "requset"/><bean class="com.spring.ioc.class08.SessionController" scope = "requset"/><bean class="com.spring.ioc.class08.ApplicationController" scope = "requset"/>

每次刷新@contraller改变
回顾

  • request:每个requset请求斗湖创建一个单独的实例
  • session:每个session都会创建一个单独的实例
  • application:每个servletContext都会创建一个单独的实例
  • websocket:每个websocket链接都会创建一个单独实例
自定义作用域
  • SimpleThreadScope作用域

MyScope.java
在这里插入图片描述
spring.xml

Bean的懒加载

Spring容器会在创建容器时提前初始化Singleton作用域的bean
但如果Bean被标记了lazy-init = “true”
那么该Bean只有在其被需要的时候才会初始化

只对singleton作用域的bean有效
多例模式不知道bean什么时候被实例化

单一的Bean需要懒加载

 <bean class = "com.example.controller.People.Beanb" id = "bean2"  scope="singleton" lazy-init="true"/>

所有的bean需要懒加载

<beans default-lazy-init="true">

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
位所有的bean都设置默认的
在这里插入图片描述

Bean初始化及销毁逻辑处理

如果Bean实例化之后执行一些逻辑 有两种方法

  • bean标签里的属性 initmethod
  • 让Bean实现InitializingBean接口

如果Bean在销毁之前需要执行一些逻辑 两种方法

  • destory-method
  • DisposableBean接口
Bean属性继承

场景1
在这里插入图片描述
简化代码
在这里插入图片描述
场景2
在这里插入图片描述
在这里插入图片描述

注解

spring2.5之后用注解取代xml

xml 与 annotation对比

在这里插入图片描述
MyConfiguration.java

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfiguration { @Bean //这里也可以用(value=“bean1命名”) public Bean bean1(){  return new Bean(); }}

Test.java

import com.example.controller.People.MyConfiguration;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Class008Test {  @Test public void test(){  ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);  Bean1 bean1 = context.getBean("bean",Bean.class);  System.out.println("bean1 = "bean1); }}

在这里插入图片描述

简化代码

conpoent-scan包扫描
在这里插入图片描述
@ component注解
在这里插入图片描述

给Bean取别名

在这里插入图片描述

通过注解注入Bean

在这里插入图片描述
构造方法和Set方法注入Bean
在这里插入图片描述
通过属性直接注入
在这里插入图片描述
实例化和注入时指定Bean的id
在这里插入图片描述
List/Set注入
直接注入List实例
在这里插入图片描述
将多个泛型实例注入到List
在这里插入图片描述
Map注入
在这里插入图片描述
多个泛型实例注入Map
在这里插入图片描述
String Integer类型的直接赋值
在这里插入图片描述
Spring Ioc容器内置借口实例注入
在这里插入图片描述
可以直接将ApplicationContext注入进来,也可以注入BeanFactory、Environment、ResourceLoader、ApplicationEventPublisher\MessagerSource及其实现类

SpringIoc注解设定Scope(作用域)

Spring预定义作用域
在这里插入图片描述
自定义作用域
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
方法注入
在这里插入图片描述
在这里插入图片描述

通过注解开启Bean的懒加载

在这里插入图片描述

通过注解编写Bean初始化及销毁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源文地址:https://www.guoxiongfei.cn/csdn/5114.html
0