Spring

1.Spring

1.1简介

  1. Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
  2. 解决企业开发的复杂性。
  3. Spring理念:使现有的技术更加容易使用,本身是个大杂烩,整合了现有的技术框架。

1.2优点

  • Spring是一个开源的免费的框架(容器);
  • Spring是一个轻量级,非入侵式(引入了spring 不会改变原来的代码,不会对原项目产生影响)的框架;
  • 控制反转(IOC)和面向切面编程(AOP);
  • 支持事务的处理,对框架整合的支持;

1.3Spring组成及扩展

  • 组成
    在这里插入图片描述

1.4扩展

  • SpringBoot:一个快速开发的脚手架,基于SpringBoot可以快速开发单个微服务。约定大于配置。
  • SpringCloud:基于SpringBoot实现的
  • 大部分公司使用Spring Boot进行快速开发,学习SpringBoot前提是掌握Spring和SpringMVC。

2.IOC理论推导

  • UserDao接口
  • UserDaoImpl接口
  • UserService业务接口
  • UserServiceImpl业务实现类

2.1控制反转思想

  • 在我们的业务中,用户的需求可能会影响我们 的源代码,我们需要根据用户的需求去修改源代码!如果程序代码量十分大,修改一次的成本十分昂贵!
  • 我们使用一个Set接口实现,发生了革命性变化
 private UserDao userDao;
    //利用set方法动态实现值的注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

  • 之前是程序主动创建对象,控制权在程序员手上!
  • 使用了set注入后,程序不在具有主动性,而是变成被动接收对象。
  • 此思想从本质解决了问题,程序员不用再管理对象的创建。系统耦合性大大降低,可以更加专注与业务实现。

2.2 IOC本质

  • 之前结构:

在这里插入图片描述

  • 反转后结构:

在这里插入图片描述

  1. IoC本质:控制反转IoC是一种设计思想,DI(依赖注入)是实现IoC(思想)的一种方法,没有IoC的程序中,我们使用面向对象编程,对象的创建和对象间的依赖关系完全硬编在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,获得依赖对象的方式反转了。
  2. IoC是Spring框架的核心内容,有很多种方式实现IoC,可以使用XML配置,也可以使用注解,最新版本的Spring可以使用零配置实现IoC.
  3. Spring容器在初始化时会先读取配置文件吗,根据配置文件或元数据与组织对象存入容器中吗,程序使用时在从IoC容器中取出需要的对象。
    在这里插入图片描述
  4. 采用XML配置Bean的时候,Bean 的定义和实现时分离的,使用注解可以把两者合为一体,。

2.3HelloSpring

  1. 在这里插入图片描述
package com.qu.dao;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
    public String toString(){
        return "Hello{"+"str'"+str+"\'"+"}";
    }
}

<?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">
<!--使用Spring创建对象,id=对象名,class=需要new对象的类的路径
property相当于给对象中的属性设置一个值。
-->
    <bean id="hello" class="com.qu.dao.Hello">
    <property name="str" value="Spring"></property>
    </bean>
</beans>
  1. 使用IoC容器需要配置其元数据在resources文件中配置xml文件,先建立xml文件,文件名即上图中的applicationContest.xml
  2. 在xml中使用Spring来创建对象,在Spring中这些称作为bean。即对象=bean
  3. 加载xml文件,固定格式,ApplicationContest contest=new ClassPathXmlApplicationContest (“applicationContest”);//参数可以有多个,就是我们创建的xml文件名。
  4. contest称为获取Spring的上下文对象,我们的对象都在spring 中管理,想要使用直接去里面取出。
  5. contest.getBean(“hello”);//参数传入bean的id即可取出对应的对象。需要强转一下类型。
import com.qu.dao.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        //获取Spring上下文对象,解析beans.xml文件,生成Bean对象
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContest.xml");
        //我们的对象现在都在Spring中管理,需要时直接通过id取出,getBean的参数就是配置文件中的id
        Hello hello=(Hello)context.getBean("hello");//并不需要去new一个Hello对象
        System.out.println(hello.toString());
    }
}

代码左边的叶子表示类已经被Spring托管代码左边的叶子表示类已经被Spring托管

  1. Hello的对象谁创建的?hello对象由Spring生成。
  2. Hello的对象属性怎么设置的?hello对象属性由Spring容器设置。
  3. 控制 :谁来控制对象的创建,传统的程序的对象由程序本身控制创建,使用Spring后,现在交给Spring去做;反转:程序本身不创建对象,而编程被动的接收对象,这就是控制反转。
  4. 总结:所谓的IoC就是对象由Spring来创建,管理,分配。
        <property name="str1" ref=""/>
         <property name="str1" value=""/>
  1. ref:引用Spring中已经创建好的对象
  2. value:具体值,基本数据类型。

2.4IoC创建对象的方式

  1. 项目结构:在这里插入图片描述
  2. Spring中仍然使用无参构造创建对象
package com;

public class User {
   private String name;
   public User(){
       System.out.println("使用了无参构造");
   }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

<?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="user" class="com.User">
    <property name="name" value="野猫"></property>
</bean>
</beans>
import com.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
    //Spring容器
        ApplicationContext context =new ClassPathXmlApplicationContext("Beans.xml");
        User user=(User)context.getBean("user");//拿过来强转一下
        user.show();

    }

}


  1. Spring中使用有参构造创建对象
package com;

public class User {
   private String name;
   //创建有参构造
   public User(String name){
      this.name=name;
   }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

  1. 此时Xml出错在这里插入图片描述
  2. 解决:用有参构造创建对象有三个方法
  3. 方法一:index=0表示下标为0的参数,也就是有参构造中第一个参数
<?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">
<!--  方法一:用下标是方式创建对象  index=0表示下标为0的参数,也就是有参构造中第一个参数-->
<bean id="user" class="com.User">
    <constructor-arg index="0" value="小王"></constructor-arg>
</bean>
</beans>
  1. 方法二:还可以通过参数的类型去匹配,不建议使用,因为当有参构造有两个String参数时就会出错。
<?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">
<!--  方法二,通过类型type,String类型用一下表示形式-->
<bean id="user" class="com.User">
    <constructor-arg type="java.lang.String" value="小张"></constructor-arg>
</bean>
</beans>
  1. 方法三:ref去指向
<?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">
<!--  方法三,直接通过参数名设置,ref引用-->
<bean id="user" class="com.User">
   <constructor-arg name="name" value="小李"></constructor-arg>
</bean>
</beans>

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!

2.5Bean的配置

  1. 别名在后面引用对象名时user和user2一样。
  2. id:bean的唯一标识符,也就相当于对象名。
  3. class:bean对象所对应的权限定名,:包+类型
  4. name:也就是别名,而且name可以取多个名
<bean id="user" class="com.User" name="user3,user4">
   <constructor-arg name="name" value="小李"></constructor-arg>
</bean>
 <alias name="user" alias="user2"></alias>

2.6 import

  1. 一般用于团队开发使用,他可以将多个配置文件,导入合并为一个
  2. 定义多个beans.xml,在applicationContest.xml中导入其他几个,相当于合并
    在这里插入图片描述在这里插入图片描述
<import resource="Beans.xml"></import>
    <import resource="beans2.xml"></import>
  • 假如某项目有三个人开发,这三个人负责不同的类的开发,而不同的类需要注册在不同的bean中,我们可以利用import将所有的beans合并为一个总的配置文件,使用时只用使用这个总的配置。

3. 依赖注入

3.1构造器注入(已讲2.4)

3.2Set方式注入【重点】

  • 依赖注入:Set注入
  • 依赖:bean对象的创建依赖于容器
  • 注入:bean对象中所有属性由容器来注入
  • 环境搭建:
  • (1)复杂类型
package com.qu.pojo;
//复杂类型,将地址作为一个引用对象
public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

  • (2)真实测试对象
package com.qu.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Student {
    private String name;
    private Address address;
    private String[] book;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private Properties info;//配置类型,学生信息我们自定义
    private String wife;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBook() {
        return book;
    }

    public void setBook(String[] book) {
        this.book = book;
    }

    public List<String> getHobbys() {
        return hobbys;
    }

    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }
}

  • (3)Beans.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">
<!--第一种,普通值注入,value-->
    <bean name="student" class="com.qu.pojo.Student">
        <property name="name" value="张三"></property>
    </bean>
</beans>
  • 测试类:
import com.qu.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context =new ClassPathXmlApplicationContext("Beans.xml");
        Student student = (Student)context.getBean("student");
        System.out.println(student.getName());
    }
}

  • (4)完善注入信息,集合数组等值的注入
<?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">
<!--    先引入Address-->
    <bean id="address" class="com.qu.pojo.Address"/>
    <bean name="student" class="com.qu.pojo.Student">
        <!--第一种,普通值注入,value-->
        <property name="name" value="张三"></property>
        <!--  第二种注入,bean注入,使用ref-->
        <property name="address" ref="address"></property>
        <!-- 数组注入,ref-->
        <property name="book"  >
            <array>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>三国</value>
            </array>
        </property>
        <!-- list注入-->
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>看电影</value>
                <value>敲代码</value>
            </list>
        </property>
        <!--  map注入-->
        <property name="card">
            <map>
                <entry key="身份证" value="12345678"></entry>
                <entry key="银行卡" value="87654321"></entry>
            </map>
        </property>
        <!--set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>CF</value>
            </set>
        </property>
<!--  null值注入-->
        <property name="wife" >
            <null></null>
        </property>
<!-- Properties-->
        <property name="info">
            <props>
                <prop key="学号">12345</prop>
                <prop key="分数">90</prop>
            </props>
        </property>
    </bean>
</beans>

3.3拓展方式

4.Bean作用域(Bean scopes)

4.1单例模式(spring默认就是单例)

定义bean的scope=singleton,只有一个实例。共享一个对象。

<bean id="user" class="com.User" name="user3,user4" scope="singleton">
   <constructor-arg name="name" value="小李"></constructor-arg>
</bean>
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context =new ClassPathXmlApplicationContext("Beans.xml");

        User user=(User)context.getBean("user3");//拿过来强转一下
        User user2=(User)context.getBean("user4");
        System.out.println(user==user2);

    }

}

取出对象user和user2,他俩其实指向同一个东西。
在这里插入图片描述

4.2原型模式,每次从容器中get的时候都会产生一个新对象

设置scope为prototype

<bean id="user" class="com.User" name="user3,user4" scope="prototype">
   <constructor-arg name="name" value="小李"></constructor-arg>
</bean>
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context =new ClassPathXmlApplicationContext("Beans.xml");

        User user=(User)context.getBean("user3");//拿过来强转一下
        User user2=(User)context.getBean("user4");

        System.out.println(user.hashCode());
        System.out.println(user2.hashCode());
        System.out.println(user==user2);

    }

}

在这里插入图片描述

4.3其他的request,session,application,这些只能在web开发中用到

5.Bean的自动装配

  • 自动装配是Spring满足bean依赖的一种方式。
  • Spring上下文中自动寻找,并自动给bean装配属性。
  • 在Spring中有三种装配的方式。(1)在xml中显示配置(手动编写xml)(2)在java中显示配置(3)隐式的自动装配(重点)

5.1测试

  • 环境搭建:(1)一个人拥有两个宠物(2)创建Cat,Dog,People三个类(3)并在Xml中配置(4)在MyTest中测试
package com.qu;

public class Cat {
    public void shout(){
        System.out.println("喵喵");
    }
}

package com.qu;

public class Dog {
    public void shout(){
        System.out.println("汪汪");
    }
}

若更改id名称后不可用


    <bean id="cat" class="com.qu.Cat"></bean>
    <bean id="dog" class="com.qu.Dog"></bean>
    <bean id="people" class="com.qu.People">
        <property name="name" value="老王"></property>
        <property name="cat"  ref="cat"></property>
        <property name="dog" ref="dog"></property>
import com.qu.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context= new ClassPathXmlApplicationContext("beans.xml");
        People people= context.getBean("people", People.class);
       people.getDog().shout();
       people.getCat().shout();
    }

}

5.2ByName自动装配

    <bean id="cat" class="com.qu.Cat"></bean>
    <bean id="dog" class="com.qu.Dog"></bean>
<!--    byname的原理:会自动在容器上下文中查找和自己对象Set方法中值对应的beanid-->
    <bean id="people" class="com.qu.People" autowire="byName">
        <property name="name" value="老王"></property>
     </bean>

在这里插入图片描述

5.3byType自动配置

更改id名称不影响。因为他是根据类型class来判断。


    <bean id="cat" class="com.qu.Cat"></bean>
    <bean id="dog222" class="com.qu.Dog"></bean>
<!--    byname的原理:会自动在容器上下文中查找和自己对象Set方法中值对应的beanid-->
<!--    byType的原理:会自动在容器上下文中查找和自己对象属性类型相同的bean-->
    <bean id="people" class="com.qu.People" autowire="byType">
        <property name="name" value="老王"></property>
     </bean>

5.4小结

  1. byName:需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性set方法的值一致。
  2. byType:需要保证bean的所有的class唯一,并且这个bean需要和自动注入的属性的类型一致。

5.5使用注解实现自动装配

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒今天想展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值