SpringIOC

1 概念

spring  不是一个功能性框架 一种设计层面的框架
spring核心:ioc和aop
IOC:控制反转 Inversion of Control
    spring把程序所依赖所有对象的创建、初始化、分配、管理、销毁等工作交给spring容器
    对象的所有控制权交给了spring容器  而不再是由程序做主
DI:依赖注入Dependency injection   
   在运行时期  spring容器把程序依赖的对象动态的注入到程序中 

2 ioc案例1

创建java项目

导入jar包

logging-1.1.1.jar:日志jar
log4j-1.2.15.jar:日志jar
asm-3.0.1.RELEASE-A.jar:字节码文件解析jar
RELEASE-A.jar:javabean实体类依赖的jar
context-3.0.1.RELEASE-A.jar:spring功能控制jar---验证/jmail
core-3.0.1.RELEASE-A.jar:springioc核心jar
expression-3.0.1.RELEASE-A.jar:spring表达式依赖的jar

创建srping的核心配置文件

spring_ioc_core.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<!-- xsd文件对当前xml文件进行语法检查 :规定有哪些标签 有哪些属性 标签的嵌套关系-->
	
</beans>

创建实体类

public class Student {
    private Integer sid;
    private String sname;
    private String sex;
    private Integer sage;
    private Boolean sdy;
    ...
}

在核心配置文件中通过bean标签来创建对象

<!-- 通过bean标签创建程序依赖的对象 -->
<!-- Integer sid, String sname, String sex, Integer sage, Boolean sdy -->
<bean name="s1" class="com.zhiyou100.ioc.day01.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>
<bean name="s2" class="com.zhiyou100.ioc.day01.Student">
    <constructor-arg  index="0"  value="1002" />
    <constructor-arg  index="2"  value="韩红" />
    <constructor-arg  index="1"  value="女" />
    <constructor-arg  index="4"  value="false" />
    <constructor-arg  index="3"  value="33" />
</bean>

测试类

//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou100/ioc/day01/spring_ioc_core_01.xml");
//通过上下文对象的getbean方法 由bean的name值获取javabean对象
Student stu1=(Student)context.getBean("s1");
System.out.println(stu1);
Student stu2=(Student)context.getBean("s2");
System.out.println(stu2);
context.close();

3 研究springioc

3.1spring创建bean的特点

1:默认情况下 项目启动:spring容器读取核心配置文件 就创建bean标签对应的javabean对象
2:spring中bean标签是单例对象:一个bean标签默认只创建一个对象
  同一个bean标签调用多次 创建的是同一个对象
3:默认调用实体类的无参数的构造方法创建对象:如果没有无参数的构造方法:抛出异常:NoSuchMethodException
4:如果bean标签中是property标签:javabean通过set方法给属性赋值
  如果bean标签中是constructor-arg标签:javabean通过构造方法参数列表给属性赋值 

3.2获取springcontent的方式

//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou100/ioc/day01/spring_ioc_core_01.xml");
//通过上下文对象的getbean方法 由bean的name值获取javabean对象
Student stu1=(Student)context.getBean("s1");
System.out.println(stu1);
context.close();

//创建spring上下文对象方式2:FileSystemXmlApplicationContext
FileSystemXmlApplicationContext context2=new FileSystemXmlApplicationContext("src/com/zhiyou100/ioc/day01/spring_ioc_core_01.xml");
Student stu4=(Student)context2.getBean("s1");
System.out.println(stu4);
context.close();

3.3多个核心配置文件

  • 方式1:ClassPathXmlApplicationContext的参数是不定参数 可以指定多个配置文件的路径
//多个spring核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou100/ioc/day01/spring_ioc_core_01.xml","com/zhiyou100/ioc/day01/spring_ioc_core_02.xml");
  • 方式2:在主配置文件中通过import标签引入所有的其他配置文件
<import resource="spring_ioc_core_02.xml"/><!-- 相对于当前配置文件的目录 -->

3.4 给属性赋值方式

  • 通过set方法给属性赋值:调用的property标签
<bean name="s1" class="com.zhiyou100.ioc.day01.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>
  • 通过构造方法参数列表给属性赋值:调用constructor-arg标签
<bean name="s1" class="com.zhiyou100.ioc.day01.Student">
    <constructor-arg  index="0"  value="1002" />
    <constructor-arg  index="2"  value="韩红" />
    <constructor-arg  index="1"  value="女" />
    <constructor-arg  index="4"  value="false" />
    <constructor-arg  index="3"  value="33" />
</bean>

3.5 bean关联

  • 实体类Teacher
public class Teacher implements Serializable{//注意实现序列化
	private Integer tid;
	private String tname;
	private String tsex;
    ...
}
  • 实体类Student
public class Student implements Serializable{
    private Integer sid;
    private String sname;
    private String sex;
    private Integer sage;
    private Boolean sdy;
    //定义引用记录当前学生的老师
    private Teacher  teacher;
    ...
}
  • 配置bean
<bean name="s1" class="com.zhiyou100.ioc.day02.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- 给teacher属性赋值:private Teacher  teacher -->
    <!-- property和constructor-arg标签的value属性:给单值数据(基本数据类型+字符串)赋值 -->
    <!-- property和constructor-arg标签的ref属性:给引用类型数据(对象类型)赋值 -->
    <property name="teacher" ref="t1"/>
</bean>

<bean name="t1" class="com.zhiyou100.ioc.day02.Teacher">
    <property name="tid"  value="1"/>
    <property name="tname"  value="张老师"/>
    <property name="tsex"  value="男"/>
</bean>

3.6 bean作用域

<!-- bean的作用域:通过scope属性制定 -->
<!-- scope属性的值:
      singleton:单例  每次调用此bean获取的永远是同一个对象 (默认)
      prototype:多例  每次调用bean 获取都是新的对象
      request: 适用于web项目:同一个请求链 调用同一个bean获取的是同一个对象
      session: 适用于web项目:同一个回话 调用同一个bean获取的是同一个对象
      global-session: 适用于web项目:同一个servletcontext 调用同一个bean获取的是同一个对象
  -->
<bean name="s2" class="com.zhiyou100.ioc.day02.Student" scope="prototype">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

3.7 bean懒加载

<!-- bean的懒加载:默认情况下scope=singleton的bean 项目启动spring容器加载核心配置文件就会创建bean对应的对象 
      开头通过lazy-init="true"属性来指定 bean标签第一次被调用时才创建对象
 -->
<bean name="s3" class="com.zhiyou100.ioc.day02.Student" scope="singleton" lazy-init="true">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

3.8 bean生命周期

对象创建 对象初始化 对象调用 对象销毁

  • 实体类Student

public class Student implements Serializable{
	public void init(){
		System.out.println("初始化方法:++++++:public void init()");
	}
	public void destory(){
		System.out.println("销毁方法::------:public void destory()");
	}
    。。。
}
  • bean配置
<!-- bean的生命周期:
   bean对象创建完后会立刻调用init-method属性对应的方法进行对象的初始化
   springcontext关闭之前会调用destroy-method属性对应的方法进行对象的销毁
  -->
<bean name="s4" class="com.zhiyou100.ioc.day02.Student"  init-method="init" destroy-method="destory">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

3.9 bean的集合属性

  • 实体类
public class Worker  implements Serializable{
	 private Integer wid;
	 private Teacher teacher;
	 private int[] arrInt;
	 private Teacher[] arrTea;
	 private List<Teacher> listTea;
	 private List<Integer> listInt;
	 private Set<Integer> setInt;
	 private Map<String, Teacher> map;
    ...
}
  • 配置文件
<!-- 集合类型的属性-->
<bean name="tea1" class="com.zhiyou100.ioc.day02.Teacher">
    <property name="tid" value="11"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value="男"/>
</bean>
<bean name="tea2" class="com.zhiyou100.ioc.day02.Teacher">
    <property name="tid" value="12"/>
    <property name="tname" value="田老师"/>
    <property name="tsex" value="男"/>
</bean>
<bean name="tea3" class="com.zhiyou100.ioc.day02.Teacher">
    <property name="tid" value="13"/>
    <property name="tname" value="陈老师"/>
    <property name="tsex" value="女"/>
</bean>

<bean name="w1" class="com.zhiyou100.ioc.day02.Worker">
    <!-- 	     	 private Integer wid; -->
    <property name="wid" value="1001"/>
    <!-- 			 private Teacher teacher; -->
    <property name="teacher" ref="tea1"/>
    <!-- 			 private int[] arrInt; -->
    <property name="arrInt">
        <array value-type="int">
            <value>111</value>
            <value>112</value>
            <value>113</value>
            <value>114</value>
        </array>
    </property>

    <!-- 			 private Teacher[] arrTea; -->
    <property name="arrTea">
        <array value-type="com.zhiyou100.ioc.day02.Teacher">
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
        </array>
    </property>

    <!-- 			 private List<Teacher> listTea; -->
    <property name="listTea">
        <list value-type="com.zhiyou100.ioc.day02.Teacher">
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
        </list>
    </property>

    <!-- 			 private List<Integer> listInt; -->
    <property name="listInt">
        <list value-type="java.lang.Integer">
            <value>21</value>
            <value>31</value>
            <value>41</value>
        </list>
    </property>

    <!-- 			 private Set<Integer> setInt; -->
    <property name="setInt">
        <set value-type="java.lang.Integer">
            <value>22</value>
            <value>32</value>
            <value>42</value>
            <value>22</value>
            <value>32</value>
            <value>42</value>
        </set>
    </property>

    <!-- 			 private Map<String, Teacher> map; -->
    <property name="map">
        <map key-type="java.lang.String" value-type="com.zhiyou100.ioc.day02.Teacher">
            <entry key="key1" value-ref="tea1"/>
            <entry key="key2" value-ref="tea2"/>
            <entry key="key3" value-ref="tea3"/>
        </map>
    </property>
</bean>

3.10 工厂模式

目标对象的创建 由factory类的方法来实现

实例工厂模式:提供创建目标对象的工厂方法是实例方法

  • 实例工厂类
public class FactoryInstance implements Serializable{
	public Teacher getInstance(){
		Teacher t=new Teacher();t.setTid(1);t.setTname("韩梅梅");t.setTsex("女");
		return t;
	}
}
  • 配置
<!-- 实例工厂模式 -->
<!-- 创建bean:获取实例工厂对象 -->
<bean name="factoryInstance"  class="com.zhiyou100.ioc.day02.FactoryInstance"/>
<!-- 创建bean:调用实例工厂对象的方法获取目标对象 -->
<bean  name="tea01" factory-bean="factoryInstance" factory-method="getInstance"/>

静态工厂模式:提供创建目标对象的工厂方法是静态方法

  • 静态工厂类
public class FactoryStatic implements Serializable{
	public static Teacher getInstance(){
		Teacher t=new Teacher();t.setTid(1);t.setTname("韩梅梅");t.setTsex("女");
		return t;
	}
}
  • 配置
<!-- 静态工厂模式 -->
<bean  name="tea02" factory-method="getInstance" class="com.zhiyou100.ioc.day02.FactoryStatic" />

3.11 自动装配:自动关联对象的属性赋值

  • 实体类
public class Student {
    private Integer sid;
    private String sname;
    private String sex;
    private Integer sage;
    private Boolean sdy;
    private Teacher teacher;
    ...
}
  • 配置
<!-- autowire="byName":自动给对象类型的属性赋值:bean名字和属性名一致 -->
<bean name="s2" class="com.zhiyou100.ioc.day03.Student" autowire="byName">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- private Teacher teacher; -->
</bean>

<!-- autowire="byType":如果找到一个指定类型的bean 直接赋值
  如果找到多个 赋值bean的名字与属性名相同的
  如果找到多个 但没有bean的名字与属性名字相同的  报错:UnsatisfiedDependencyException
 -->
<bean name="s3" class="com.zhiyou100.ioc.day03.Student" autowire="byType">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- private Teacher teacher; -->
</bean>

4 注解形式的ioc

4.1 导入jar

注解的jar和配置的jar完全一样

4.2 在核心配置文件中引入context的命名空间和xsd

<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!--命名空间和xsd文件都是复制修改的-->
</beans>

4.3 使用context标签指定添加了注解的实体类的位置

<!-- 添加标签指定添加注解的实体类位置 -->
<context:component-scan base-package="com.zhiyou100.ioc.day04"/>

4.4 在实体类上添加注解

package com.zhiyou100.ioc.day04;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.jws.soap.InitParam;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Repository    //创建bean的注解:给dao持久层的类添加的注解
//@Controller    //创建bean的注解:给controller控制层的类添加的注解
//@Service       //创建bean的注解:给service业务层的类添加的注解
@Component("s2")  //创建bean的注解:不确定当前bean具体属于那一层  可以加属性:用于指定bean的名字  不加默认是类名首字母小写
//@Scope("prototype") //指定bean的作用域
@Lazy//懒加载  只适用于单例模式
public class Student {
    {
        System.out.println("构造代码块!!");
    }
    //@Value("1001")给属性赋值:可以加载属性上  也可以加在set方法上
    @Value("1001")
    private Integer sid;
    @Value("韩庚")
    private String sname;
    @Value("男")
    private String sex;
    @Value("19")
    private Integer sage;
    private Boolean sdy;

    //@Autowired  //自动装配:策略和byType类似
    //@Resource(name="teacher")//自动装配:name指定bean的名字
    @Resource
    private Teacher teacher;
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getSage() {
        return sage;
    }
    public void setSage(Integer sage) {
        this.sage = sage;
    }
    public Boolean getSdy() {
        return sdy;
    }
    @Value("true")
    public void setSdy(Boolean sdy) {
        this.sdy = sdy;
    }	
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", sex=" + sex + ", sage=" + sage + ", sdy=" + sdy
            + ", teacher=" + teacher + "]";
    }
    public Student(Integer sid, String sname, String sex, Integer sage, Boolean sdy) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.sex = sex;
        this.sage = sage;
        this.sdy = sdy;
    }
    public Student() {
        super();
    }

    @PostConstruct
    public void initMethod(){
        System.out.println("public void initMethod()");
    }
    @PreDestroy
    public void destroyMethod(){
        System.out.println("public void destroyMethod()");
    }
}
posted @ 2021-11-08 10:34  RenVei  阅读(46)  评论(0编辑  收藏  举报