欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring IOC

程序员文章站 2022-07-12 13:59:16
...

一、介绍

1、IOC(Inversion of Control)。

        控制反转IOC(Inversion of Control)和依赖注入DI(Dependency Injection)是同一个概念,IOC是目的,DI是方法手段。通常由调用者创建被调用者的实例,但spring中创建被调用者的实例由spring完成,然后注入调用者。

2、容器。

        Spring 容器是 Spring 框架的核心,是用来管理对象的,用Map来存储。在java项目中的实现org.springframework.context.ApplicationContext接口的类的实例,或者在xml配置文件中进行配置。一个Spring容器就是某个实现了ApplicationContext接口的类的实例。

        Spring容器基本分为两种,一个是ApplicationContext(继承BeanFactory),一个是BeanFactory,其中BeanFactory只提供基本的DI功能。因为Spring容器是基于ICO进行控制对象的,所以也称为ICO容器。

3、注入方式。

  1)、配置注入(Xml)。配置注入分为set注入和构造注入,分别对应对象中的属性和构造方法。

  2)、配置注入(Java)。就是用java代码来实现xml配置的实现。要使用到注解@ Configuration和@Bean来实现。

  3)、注解注入。先需要在xml配置文件或者java启动类上声明扫描的包。然后在被引入类上要声明注解:

                @Component,无明确的。

                @Controller,控制层(controller)。

                @Service,业务逻辑层(service)。

                @Repository,数据访问层(dao)。    最后在引入地方的字段上面使用注解@Autowire或者@Resource进行注入,基

    本类型字段的注入使用@Value注解。

4、注解@Autowire和@Resource的区别。

        对比项       @Autowire    @Resource
        注解来源    Spring注解    JDK注解(JSR-250标准注解,属于J2EE)
        装配方式    优先按类型    优先按名称
        属性           required         name、type
        
        Resoure的装配顺序
        如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
        如果指定name属性,则按照名称(by-name)装配,未找到则抛异常;
        如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常;
        既未指定name属性,又未指定type属性,则按照名称(by-name)装配;如果未找到,则按照类型(by-type)装配。

二、配置注入(Xml)

1、在main包下新建resource文件夹,然后在其上面点击右键,将其改为资源路径。

Spring IOC

2、在resource下面新建spring.xml文件。

Spring 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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="userServiceByXml" class="com.zxj.dao.service.impl.UserServiceImpl"/>

    <!--set注入-->
    <bean id="userByXml" class="com.zxj.dao.entity.User">
        <property name="name" value="set注入"/>
        <property name="age" value="12"/>
    </bean>

    <!--构造注入-->
    <bean id="userByXml2" class="com.zxj.dao.entity.User">
        <constructor-arg name="name" value="构造注入"/>
        <constructor-arg name="age" value="23"/>
    </bean>
</beans>

3、新建User.java、IUserService.java、UserServiceImpl.java。

package com.zxj.dao.entity;

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

    public User(){

    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
package com.zxj.dao.service;

import com.zxj.dao.entity.User;

public interface IUserService {
    void printInfo(User user);
}
package com.zxj.dao.service.impl;

import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;

public class UserServiceImpl implements IUserService {
    @Override
    public void printInfo(User user) {
        System.out.println(String.format("%s已经%d岁了", user.getName(), user.getAge()));
    }
}

4、测试单元测试。

package com.zxj;

import com.zxj.dao.entity.Book;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IBookService;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
    @Test
    public void iocTest1() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");

        User user = new User();
        user.setAge(10);
        user.setName("卓小杰");

        System.out.println("通过名字,获取bean对象: ");
        IUserService userService = (UserServiceImpl) ac.getBean("userService");
        userService.printInfo(user);

        System.out.println("通过类型,获取bean对象: ");
        IUserService userService2 = ac.getBean(UserServiceImpl.class);
        userService2.printInfo(user);
    }
}

5、结果。

Spring IOC

三、配置注入(Java)

1、新建JavaBeanConfig.java。

package com.zxj.config;

import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JavaBeanConfig {
    @Bean("userServiceByConfig")
    public IUserService userServiceByConfig() {
        return new UserServiceImpl();
    }

    @Bean("userByConfig")
    public User userByConfig() {
        User user = new User();
        user.setName("卓小杰");
        user.setAge(16);
        return user;
    }
}

3、在spring.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--要扫描包-->
    <context:component-scan base-package="com.zxj"/>
</beans>

4、测试单元测试。

package com.zxj;

import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
    /**
     * aaa@qq.com和@Resource的对比
     * 对比项    @Autowire    @Resource
     * 注解来源    Spring注解   JDK注解(JSR-250标准注解,属于J2EE)
     * 装配方式    优先按类型  优先按名称
     * 属性      required   name、type
     * <p>
     * aaa@qq.com的装配顺序
     * 如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
     * 如果指定name属性,则按照名称(by-name)装配,未找到则抛异常;
     * 如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常;
     * 既未指定name属性,又未指定type属性,则按照名称(by-name)装配;如果未找到,则按照类型(by-type)装配。
     */
    @Autowired
    @Qualifier("userServiceByConfig")
    private IUserService userServiceByConfig;
    @Resource(name = "userByConfig")
    private User userByConfig;

    @Test
    public void iocTest2() {
        userServiceByConfig.printInfo(userByConfig);
    }
}

5、结果。

Spring IOC

四、注解注入

1、在spring.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--要扫描包-->
    <context:component-scan base-package="com.zxj"/>
</beans>

2、新建Book.java、IBookService.java、BookServiceImpl.java。

package com.zxj.dao.entity;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Book {
    @Value("基督山伯爵")
    private String name;
    @Value(value = "24.8")
    private Double price;

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}
package com.zxj.dao.service.impl;

import com.zxj.dao.entity.Book;
import com.zxj.dao.service.IBookService;
import org.springframework.stereotype.Service;

@Service("bookService")
public class BookServiceImpl implements IBookService {
    @Override
    public void printInfo(Book book) {
        System.out.println(String.format("%s的价格是%f", book.getName(), book.getPrice()));
    }
}
package com.zxj.dao.service;

import com.zxj.dao.entity.Book;

public interface IBookService {
    void printInfo(Book book);
}

3、测试单元测试。

package com.zxj;

import com.zxj.dao.entity.Book;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IBookService;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
    @Autowired
    private IBookService bookService;
    @Autowired
    private Book book;

    @Test
    public void iocTest3() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");

        Book book2 = new Book();
        book2.setName("悲惨世界");
        book2.setPrice(32.5);
        System.out.println("通过new,获取实体对象");
        bookService.printInfo(book2);

        System.out.println("通过@Component和@Value,获取实体对象: ");
        bookService.printInfo(book);
    }
}

4、结果。

Spring IOC

相关标签: spring IOC