Spring框架1(Spring简介、Spring中的IOC、Spring中IOC创建对象的方式、Spring中的DI(依赖注入)、Scope作用域)

1.Spring简介

[1]为什么学习Sping框架

目前遇到的问题

  • A、我们现在使用的MVC模式,发现层和层之间的耦合度太高了
  • B、目前书写代码的后期扩展性不高
[2]解决方案

使用Spring:    Spring是解决业务层和其他各层之间的耦合问题

[3]Spring简介

Spring:  Spring framework
创始人:Rod Johnson
轮子理论:不新建轮子,使用旧轮子

[4]学习框架必备三要素

jar包  http://spring.io/projects
api  https://docs.spring.io/spring/docs/current/spring-framework-reference/
源码  https://github.com/spring-projects/spring-framework/tags

[5]Spring学习的核心技能点

A、IOC:控制反转-----帮助我们创建对象的
B、AOP:面向切面----提升代码的拓展性
C、TX:声明式事务----事务管理

2.Spring中的IOC

[1]责任链

我们使用MVC进行开发的时候,数据在各层之间进行传递,数据在业务上构成一个链条,该链条称之为责任链

[2]基于责任链开发的缺点

基于责任链开发模式,我们发现代码层和层之间相互调用,造成代码层和层之间的耦合性过高。而我们写代码的时候讲究的原则是:高内聚,低耦合

[3]解决方案

Spring  IOC:控制反转

[4]Spring  IOC:控制反转

控制:就是指Spring创建对象的过程
反转:创建对象这个过程本来是由程序员做的,现在反交给Spring  IOC进行创建

[5]代码实现

A、导包
在这里插入图片描述
B、创建类


public class Student {
   
    public  Student(){ //对象一旦被创建,该构造方法就会被调用
        System.out.println("----对象已创建----");
    }
    public void  eat(){
        System.out.println("---eat()方法---");
    }
}

C、书写配置文件applicationContext.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">

    <!--相当于代替了  Student student = new Student()-->
    <bean id="student" class="cn.qt.spring1.Student"></bean>

</beans>

D、解析XML调用对象

package cn.qt.spring1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        //Student student = new Student();
        //[1]解析XML文档
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
       // Student student = (Student) app.getBean("student");该方法未指定对象的类,默认为OBject类,需要强转成其对应的类

        Student student1 = app.getBean("student", Student.class);//该方法指定了对象的类,对象的类即为getBean()方法的第二个参数
        student1.eat();
    }
}

E、运行结果
在这里插入图片描述
即完成了通过Spring IOC创建对象并调用对象的方法
Spring IOC的好处:实现了各层之间的解耦

3.Spring中IOC创建对象的方式

A、使用无参构造
B、使用有参构造
C、使用工厂方法模式

[1]使用无参构造
 <bean id="student" class="cn.qt.spring1.Student"></bean>
[2]使用有参构造
 <!--
        Student stu2 = new Student("张三","男",18);
        注意:<constructor-arg>标签中
            [1]name的值和构造器的形参是保持一致的,而非实体类的属性。
            [2]形参的顺序不用和标签中的顺序保持一致
            [3]使用name属性调用,但是除了name属性,
            还有index(从0开始),type:数据类型
            建议三者都写上,即可确定唯一的构造方法
    -->
    <bean id="stu2" class="cn.qt.spring2.Student">

        <constructor-arg name="age" value="18" index="2" type="int"></constructor-arg>
        <constructor-arg name="name" value="张三" index="0" type="java.lang.String"></constructor-arg>
        <constructor-arg name="sex" value="男" index="1" type="java.lang.String"></constructor-arg>
    </bean>

[3]使用工厂方法模式

设计模式:是为了解决某一类问题的产生
用简单工厂模式创建对象
1.People接口

public interface People {
    public void eat();
    public void run();
}

2.Teacher类

public class Teacher implements People{
    public Teacher(){
        System.out.println("老师对象已被创建");
    }

    @Override
    public void eat() {
        System.out.println("老师吃的方法");
    }

    @Override
    public void run() {
        System.out.println("老师跑的方法");
    }
}

3.Student类

public class Student implements People {
    public Student(){
        System.out.println("学生对象已被创建");
    }

    @Override
    public void eat() {
        System.out.println("学生吃的方法");
    }

    @Override
    public void run() {
        System.out.println("学生跑的方法");
    }
}

4.Factory方法

public class Factory {


    public People getInterface(String param){
        if ("student".equals(param)){
            return new Student();
        }else if ("teacher".equals(param)){
            return  new Teacher();
        }else {
            return null;
        }
    }
//getInterface2除了是静态方法外与getInterface无任何区别
    public static People getInterface2(String param){
        if ("student".equals(param)){
            return new Student();
        }else if ("teacher".equals(param)){
            return  new Teacher();
        }else {
            return null;
        }
    }
}

5.applicationContext.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">
    <!-- [3]用简单工厂模式创建对象   -->
    <!-- Factory factory=new Factory() 非静态方法  -->
    
    <bean id="factory" class="cn.qt.spring3.Factory"></bean>
    <!-- 相当于People teacher=factory.getInterface(teacher)   -->
    <bean id="getInterface" factory-bean="factory" factory-method="getInterface">
        <constructor-arg name="param" value="teacher"></constructor-arg>
    </bean>
    
    <!-- 相当于Factory.getInterface2("student");  静态方法 -->
    <bean id="factory2" class="cn.qt.spring3.Factory" factory-method="getInterface2">
        <constructor-arg name="param" value="student"></constructor-arg>
    </bean>
</beans>

4.Spring中的DI(依赖注入)

[1]DI(依赖注入)的概念

依赖:一个类在另一个类中作为全局属性时
注入:通过外部给自己属性(或其他内容)进行赋值
作用:给创建好的对象中的全局的属性或者对象进行赋值的操作

[2]DI的3种注入方式

两个实体类Class和Student
1.Clazz中包括以下属性和set()、get()方法、有参构造无参构造等

	private String clazzno;
    private String cname;

2.Student中包括括以下属性和set()、get()方法、有参构造无参构造等

 	private String stuno;
    private String stuName;
    private int age;
    private String sex;
    private Clazz clazz;

A、使用有参构造进行DI注入

 <!--[1]使用有参构造进行DI注入-->
    <bean id="cla" class="cn.qt.spring4.Clazz">
        <constructor-arg name="clazzno" value="501"></constructor-arg>
        <constructor-arg name="cname" value="java1班"></constructor-arg>
    </bean>
    <bean id="stu" class="cn.qt.spring4.Student">
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="stuno" value="001"></constructor-arg>
        <constructor-arg name="stuName" value="张三"></constructor-arg>
        <constructor-arg name="sex" value="男"></constructor-arg>
        <constructor-arg name="clazz" ref="cla"></constructor-arg>
    </bean>

B、使用set()方法进行DI注入

	
	<bean id="cla" class="cn.qt.spring4.Clazz">
        <constructor-arg name="clazzno" value="501"></constructor-arg>
        <constructor-arg name="cname" value="java1班"></constructor-arg>
    </bean>
     <!-- [2]使用set方法进行DI注入
     
		name:对象的属性名
        value和ref的使用场景:
        value:如果注入的属性时基本的属性类型(包括String),则使用value
        ref:如果注入的属性类型是对象时,使用ref
	-->
    
   <bean id="stu" class="cn.qt.spring4.Student">
        <property name="stuno" value="002"></property>
        <property name="stuName" value="李四"></property>
        <property name="sex" value="女"></property>
        <property name="age" value="18"></property>
        <property name="clazz" ref="cla"></property>
    </bean>

C、DI自动注入

<!-- [3]DI中的自动注入-->
 <bean id="clazz" class="cn.qt.spring4.Clazz">
        <constructor-arg name="clazzno" value="501"></constructor-arg>
        <constructor-arg name="cname" value="java1班"></constructor-arg>
 </bean>

    <!-- autowire="byName/byType/constructor"
        底层走的是set方法
        byName:在当前xml中被注入的【bean的id名称】和需要注入实体的【属性名】一致,才进行匹配注入。否则则为null
        byType:在当前的xml中被注入的【bean标签的类型】和需要注入实体中的【属性的类型】一致,才进行匹配注入。否则则为null
        底层走的是构造器
        constructor:这个时候首先会根据[有参构造器的形参名]名称进行查找,如果名称没有一致的,在根据类型[有参构造器的类型]进行查找
      需要注意:*在指定的类中必须提供合适的(构造器中有且仅有该类型的对象)有参构造器才可以
      -->
     
    <bean id="stu" class="cn.qt.spring4.Student" autowire="constructor"></bean>
    
[3]其他类型的注入

A、基本类型(Sting)
B、对象类型
C、数组类型
D、List
E、Set
F、Map

实体类User中的属性为

 	private String [] attr;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
 <!-- 特殊类型的注入-->
    <bean id="user" class="cn.qt.spring4.User">
        <property name="attr">
            <array>
                <value>A</value>
                <value>B</value>
                <value>C</value>
                <value>D</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>A</value>
                <value>B</value>
                <value>C</value>
            </list>
        </property>
        <property name="set">
            <set><!--set两种属性:无序性和唯一性,两个value为A的标签只会保存一个-->
                <value>A</value>
                <value>A</value>
                <value>C</value>
                <value>D</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry>
                    <key><value>A</value></key>
                    <value>1</value>
                </entry>
            </map>
        </property>
    </bean>

5.Scope作用域详解

  1. < bean>标签的一个属性,控制如何实例化对象。在默认情况下,Spring中的每个对象都是单例的(有效范围:同一个< bean>标签),即一个标签中获取的对象总是同一个。
  2. Scope属性可取值
    2.1singleton:默认值,单例的。使用ApplicationContext.xml启动时实例化。
    2.2 protopyte:原型,每次使用getbean方法时都实例化一个对象。
    2.3 request:每次请求时实例化一个对象。
    2.4 session:每次产生session(HttpSession)时实例化。
    2.5 application:产生application对象时实例化,一般都实例化一次。
    2.6 golbal session:全局Golbal Session,web应用中一个新的HttpSession对象,由spring-webmvc-portlet提供
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值