Spring(一):核心之IOC

1.Spring 简介

  • Spring是 分层 的轻量级开源框架
  • Spring核心是IOC(控制反转) 和 AOP(面向切面编程)
    什么是IOC和AOP放到后面讲解
  • Spring提供了对各种优秀框架的支持和 整合

2.Spring 的优点

2.1 IOC解耦

  • 可以将对象间的依赖关系交由Spring管理
  • 避免编码造成的过度耦合

2.2 支持AOP

  • 可以使用切面编程思想对方法进行增强

2.3 支持声明式事务

  • 可以通过配置或注解的方式管理事务
  • 不需要硬编码管理事务

2.4 方便测试
2.5 方便集成
2.6使用简单
2.7设计精良

3.IOC容器

3.1 什么是IOC

IOC,英文全称(Inversion Of Control),也叫控制反转,即将对象的创建交给第三方工厂来完成,所以其底层原理是工厂设计模式

3.2 IOC的作用

1.解耦

  • 利用第三方工厂创建对象,解决代码的耦合性问题

2.存储对象

  • 可以将创建出来的对象存起来重复使用

3.管理依赖关系

  • 可以将依赖对象注入到需要的对象当中
    注:依赖注入相当于赋值的意思
    比如说有一个User类,里面有一个Account属性。则可以创建Account对象,再将其注入到User对象中。

4.管理对象的创建顺序

  • 可以根据依赖关系先后创建对象

3.3 IOC编程入门

首先创建一个maven工程:pom.xml中导入相关依赖,Spring IOC需要的依赖为spring-context。为了方便测试导入junit依赖
如代码所示:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>ithaibo</groupId>
  <artifactId>spring01_ioc_02</artifactId>  
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>

<!--    导入spring ioc依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

<!--    导入单元测试依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

  </dependencies>

</project>

虽然只导入了spring-context,其实包括了这么多
在这里插入图片描述
导入了相关依赖后,我们来到resource目录创建相关配置文件,如下图,一定要导入了spring的依赖后这个选项才会出来,我们取名叫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">

</beans>

我们说IOC是用来创建对象的,所以我们来新建一个User类:

package com.chenhaibo.ioc;

public class User {
    private int id;
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

接下来配置beans.xml文件,将User对象创建并添加到IOC容器中

<?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">
<!--
      定义对象: 创建对象, 并且添加到IOC容器
          id: 对象名称(唯一)
          class: 全限定类名
  -->
<bean id="user" class="com.chenhaibo.ioc.User"></bean>

</beans>

bean标签:用来创建对象,并将对象添加到IOC容器当中。

  • id属性为对象的名称,作为唯一标识,方便外界引用。
  • class属性为类的全限定类名,用来反射创建对象的

用bean标签将User对象创建并放到IOC容器中后,我们就可以直接从IOC容器中拿到User对象。
于是我们来一个测试类测试以下:

   @Test
    public void testIoc(){

        //创建IOC容器
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

        //根据字节码对象,从IOC容器中获取User对象
        User user = ioc.getBean(User.class);
        //根据id,从IOC容器中获取User对象
        User user1 = (User) ioc.getBean("user");
        System.out.println(user);
        System.out.println(user1);
        System.out.println(user==user1);
    }

这边需要介绍一下创建IOC容器的第一种方式(还有其他方式),解析资源xml文件的方式

ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

执行结果如下:

User{id=0, name='null'}
User{id=0, name='null'}
true

从结果可以看出,根据字节码对象applicationContext.xml中配置的id都可以从IOC中拿到User对象,并且两次拿到的为同一个对象,所以,bean标签创建对象默认为单例模式

其实只要bean标签中增加一个属性scope="prototype"就可以变成多例模式:
如果不配置,**默认是scope=“singleton”**单例模式。

<bean id="user" class="com.chenhaibo.ioc.User" scope="prototype"></bean>

再次执行测试代码:

User{id=0, name='null'}
User{id=0, name='null'}
false

即两次拿到的User对象不是同一个。
以上就是spring IOC的小入门啦。

3.4 bean标签的相关属性

  • id: 名称(唯一)
  • class: 必选属性: 字节码路径
  • name: 对象的别名: 可以设置多个(,分隔或空格分隔)
  • init-method: 指定初始化方法: 在构造方法之后执行
  • destroy-method: 指定销毁方法: 在容器销毁前执行
  • lazy-init: 是否延迟创建对象
    默认是false: 不会延迟创建: 在容器创建时创建
    true: 表示延迟创建, 延迟到使用时
  • scope:定义bean的作用范围
    默认是singleton:单例模式
    prototype:多例模式

    request:web项目中,将对象存入request域中
    session:web项目中,将对象存入session域中
    globalsession:web项目中,将对象应用于集群环境,没有集群相当于
    session

3.5 IOC容器的创建方式

  • 资源文件创建方式
    ClassPathXmlApplicationContext
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 系统文件创建方式
    FileSystemXmlApplicationContext
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("D:\IDEA_Project\JavaEE\spring01_ioc_02\src\main\resources\applicationContext.xml");
  • 注解配置创建方式
    AnnotationConfigApplicationContext
@Test
public void testAnnotation() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
}

@Configuration
static class Config{

    @Bean("user")
    public User createUser(){
        return new User();
    }
}

3.6 依赖注入(DI:Dependency Injection)

  • 什么是依赖注入?
    IOC给对象赋值的一种功能
    在这里插入图片描述
  • xml 注入方式
    以上图为例,以下为xml方式依赖注入的方法

1.注入参数和注入对象

<!--    创建User对象并用构造方法的方式依赖注入-->
    <bean id="user" class="cn.ithaibo.domain.User">
        <constructor-arg name="id" value="666"/>
        <constructor-arg name="name" value="haibo"/>
<!--        注入对象,需要用ref属性引入-->
        <constructor-arg name="address" ref="address"/>
    </bean>
<!--    创建Address对象并用set方法的方式依赖注入-->
    <bean id="address" class="cn.ithaibo.domain.Address">
        <property name="province" value="福建"/>
        <property name="city" value="厦门"/>
    </bean>

值得注意的是,采用constructor-arg标签–构造方法的方式注入,实体类中需要给出带参的构造方法
采用property–set方法的方式注入(较常用),实体类中需要给出set方法
2.注入数组和注入集合
实体类Employee

public class Employee {
    private String[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties props;

    public void setArray(String[] array) {
        this.array = array;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "array=" + Arrays.toString(array) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", props=" + props +
                '}';
    }
}

通过xml文件创建Employee对象并进行依赖注入

<!--    创建Employee对象并用set方法依赖注入-->
    <bean id="employee" class="cn.ithaibo.domain.Employee">
<!--        注入数组-->
        <property name="array">
            <array>
                <value>1</value>
                <value>1</value>
            </array>
        </property>
<!--        注入list集合-->
        <property name="list">
            <list>
                <value>2</value>
                <value>2</value>
            </list>
        </property>
<!--        注入set集合-->
        <property name="set">
            <set>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </set>
        </property>
<!--        注入map集合-->
        <property name="map">
            <map>
                <entry key="id" value="666"/>
                <entry key="name" value="haibo"/>
            </map>
        </property>
<!--        注入properties-->
        <property name="props">
            <props>
                <prop key="id">666</prop>
                <prop key="name">haibo</prop>
            </props>
        </property>
    </bean>

3.7注解方式创建对象及依赖注入

为了方便经常会使用注解的方式创建对象添加到IOC容器中,用注解的方式进行依赖注入。以下为注解方式的使用方法:

在配置文件中增加如下标签(必要):

    <!-- 添加Spring组件扫描配置: 通知Spring使用了注解 -->
    <context:component-scan base-package="cn.ithaibo.domain"/>

Address实体类:

//Component注解:创建对象并添加到ioc容器中
@Component
public class Address {
//Value注解:给参数注入值
    @Value("福建")
    String province;
    @Value("厦门")
    String city;
}

User实体类:

//Component注解:创建对象并添加到ioc容器中
@Component
public class User {
	//Value注解:给参数注入值
    @Value("666")
    int id;
    //Value注解:给参数注入值
    @Value("haibo")
    String name;
    //Autowired注解:注入对象
    @Autowired
    Address address;
}

使用上述注解,可以代替applicationContext.xml中的bean标签。

  • 创建对象并添加到IOC容器中的注解有
    @Component: 修饰类
    @Repository: 修饰类, 修饰持久层类
    @Service: 修饰类, 修饰业务层类
    @Controller: 修饰类, 修饰视图层类

  • 依赖注入的注解有
    @Autowired: 修饰属性, 方法
    作用: 注入一个容器中已经存在的对象 (代替ref)
    @Qualifier: 修饰属性, 方法 (一般配合@Autowired)。
    @Resource: 相当于@Autowired+@Qualifier
    name属性:容器中对象的名称

发布了5 篇原创文章 · 获赞 3 · 访问量 103

猜你喜欢

转载自blog.csdn.net/HaibochenKK/article/details/103403768