Spring IOC介绍

IOC介绍

IOC是什么

IOC(inversion of control)即“控制反转 ”,意味着将设计好的对象交给容器控制

传统的Java程序设计,直接在对象内部通过new形式来创建对象,是程序主动去创建依赖对象,即谁调用谁来创建对象,谁来初始化对象。而IOC技术是由一个专门的容器去创建对象,IOC容器来控制对象的创建而不是显式的使用new

对象的创建交给容器管理,就是控制反转。控制反转是通过容器来完成的,Spring中提供了这样一个容器,称之为IOC容器。无论是创建对象,处理对象之间的依赖,对象的创建时间还是对象创建的数量,都是在Spring为我们提供的IOC容器上配置上对象信息即可

IOC能做什么

有了IOC容器之后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象和对象之间是松耦合的,这样方便进行测试,利于功能复用,使整个体系结构变动非常灵活

由IOC容器来帮对象找相应的依赖对象并注入,而不是对象主动去找。核心点在于,资源不是由使用资源的调用方管理,而是由不使用资源的第三方管理,第三方指的就是IOC容器

资源的集中管理,实现资源的可配置和易管理

降低了使用资源双方的依赖程度,也就是说的松耦合

Spring容器管理对象Demo

1.添加Spring核心依赖

 <!--Spring核心依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.5.RELEASE</version>
    </dependency>

2.Spring的全局配置文件

<?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-3.0.xsd">
    
</beans>

3.创建实体例(Student.java)

public class Student {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

4.IOC容器管理对象

以前是通过new形式来创建student对象的

Student student=new Student();

现在通过IOC容器,可以让IOC容器来创建和管理对象,直接在applicationContext.xml配置文件中配置对应信息

 <!--使用bean标签来标识容器管理的对象
    id属性标识对象名称,取名字
    class属性指向需要容器管理对象类全限定名
    -->
    <bean id="student" class="com.wrj.maventest.Spring.IOC.Pojo.Student"/>

5.通过容器来获取Student对象

//获取IOC容器
        String path="applicationContext.xml";
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        Student student = (Student)applicationContext.getBean("student");
        System.out.println(student);

执行结果:

以上执行结果可知,可以通过容器来获取对象实例

Spring IOC操作总结:

1.增加一个Spring配置文件

2.对XML文件进行解析

3.给定BeanFactory工厂类

4.在工厂类方法中使用反射创建bean对象

Spring中IOC容器

以上是SpringIOC容器中接口的继承关系,其中ApplicationConcext是BeanFactory的子接口,BeanFactory是SpringIOC容器所定义的最底层的接口,ApplicationConcext是BeanFactory的高级实现,并对BeanFactory的功能上做了很多的扩展,所以在大部分的工作场景下都会来使用ApplicationConcext作为IOC的容器

  • BeanFacthory:BeanFactory位于最底层,提供了比较先进的配置机制,使得任何对象的配置成为可能
  • ApplicationConcext:ApplicationConcext在BeanFactory上做了很多扩展实现
  • BeanFactory和ApplicationConcext的区别:BeanFactory的实现是按需创建,即第一次获取bean时才创建bean,ApplicationConcext会一次性创建所有的bean,ApplicationConcext也提供了一些额外的功能,比如使Spring的AOP更容易继承,也提供了Message Resource的机制(用于处理国际化支持)和通知机制

比较BeanFactory和FactoryBean???

BeanFactory是工厂类,创建bean

FactoryBean是bean,是工厂类的对象,可以放到BeanFactory里面进行管理

ApplicationConcext容器常见实现类

  • ClassPathXmlApplicationContext
ClassPathXmlApplicationContext applicationContext = new 
ClassPathXmlApplicationContext(applicationContext.xml);

读取classPath,如果配置文件在当前系统类路径下,可以优先使用ClassPathXmlApplicationContext类

  • FileSystemXmlApplicationContext
FileSystemXmlApplicationContext applicationContext= 
new FileSystemXmlApplicationContext("d://application.xml");

读取特定路径下的资源,如果文件放在文件系统路径下,则优先选择FileSystemXmlApplicationContext类

  • XmlWebApplicationContext
XmlWebApplicationContext ac= new XmlWebApplicationContext("d://application.xml");
//这时并没有初始化容器
ac.setServletContext(servletContext);//需要指定ServletContext对象
ac.setConfigLocation("/WEB-INF/applicationContext.xml");
//指定配置文件路径,开头的斜线表示web应用的根目录
ac.refresh();//初始化容器

读取网络路径下的资源

容器管理对象的过程

  1. Spring启动时读取应用程序提供Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表;
  2. 根据注册表实例化Bean
  3. 通过配置文件装配好Bean之间的依赖关系,放到Bean缓存池,为上层应用提供准备就绪的运行环境

Bean缓存池:通过HashMap实现

Spring中Bean的实例化方式

基于XML配置方式装配Bean

bean基于配置实例化的方式有三种实现:

  • 通过无参构造实例化
  • 通过静态工厂方法实例化
  • 通过普通工厂方法实例化

通过无参构造实例化

<!--无参构造实例化bean-->
    <bean id="student" class="com.wrj.maventest.Spring.IOC.Pojo.Student"/>

如果不指定构造函数,会生成一个默认的无参构造函数

如果显性的指定一个有参构造函数,不会生成默认的无参构造函数,必须再显性指定一个无参构造函数,否则实例化对象会抛出异常

通过静态工厂方法实例化

首先,使用一个工厂的静态方法返回对象

public class StaticBeanFactory {
    //提供一个获取Student对象的静态方法
    public static Student getStudent(){
        return new Student();
    }

    public static void main(String[] args) {
        //通过静态工厂获取对象
         Student student = StaticBeanFactory.getStudent();
    }
}

在配置文件中使用工厂静态方法返回对象

 <!--通过静态工厂实例化bean
    class属性是工厂类的路径
    factory-method:在工厂类中获取对象需要的方法
    -->
    <bean id="student1" class="com.wrj.maventest.Spring.IOC.StaticBeanFactory"
 factory-method="getStudent"/>

通过普通工厂实例化

通过工厂创建一个非静态方法获取对象

public class CommonBeanFactory {
    public Student getBean(){
      return new Student();
    }

    public static void main(String[] args) {
        CommonBeanFactory factory = new CommonBeanFactory();
        factory.getBean();
    }
}

配置文件中使用工厂的非静态方法返回对象

<!--通过普通工厂实例化bean-->
    <!--首先创建工厂实例-->
    <bean id="beanFactory" class="com.wrj.maventest.Spring.IOC.CommonBeanFactory"/>
    <!--指定工厂和工厂方法实例化对象-->
    <bean id="student2" class="com.wrj.maventest.Spring.IOC.Pojo.Student"
          factory-bean="beanFactory" factory-method="getBean"/>

基于注解方式装配Bean(自动装配的过程)

基于注解形式进行bean的管理比XML文件形式更加简洁

通过@Component注解标注类

@Component(value="student")
//类似于XML配置文件 @Component类似于xml中的bean标签,value值类似于xml中的id属性
public class Student {
    private Integer id;
    private String 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"
       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.xsd">

    <!--开启扫描:指定包路径或者类名,会扫描类、方法、属性上是否有注解-->
    <context:component-scan base-package="com.wrj.maventest.Spring.IOC"/>
</beans>

使用 component-scan标签方式来扫描包路径及子类路径

第一步必须引入context约束,否则无法出现context标签

在Spring中主要提供了四个注解来标注bean

  • @Component是通用的标签形式
  • @Repository  对Dao实例类进行标注,和数据库交互
  • @Service       对Service层类进行标注,处理业务逻辑
  • @Controller   对Controller层类进行标注,接收用户连接

基于Java代码装配Bean(组件扫描)

给定一个配置类在配置类上添加@Configuration,@Configuration表明当前类是一个配置类,告诉Spring上下文如何创建bean细节

@Configuration
//表明当前类是配置类
public class TestConfig {
}

将交给Spring管理的类声明为bean,编写一个方法,方法创建所需要的的bean实例,给方法添加上@Bean注解


    @Bean(name="student4")
    //name类似于xml中的id属性
    public Student student(){
        return new Student();
    }

@Bean注解会告诉Spring这个方法会返回一个对象,这个对象会被注册到Spring中

Spring中DI介绍

DI(Dependency Injection)即依赖注入,对象之间的依赖由容器在运行期决定,即容器动态的将某个依赖注入到对象之中

基于XML配置注入依赖

有参构造函数注入依赖

bean类需要实现有参构造函数

/**
     * 有参构造函数
     */
    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

在配置文件中配置参数通过有参构造函数给对象属性赋值

 <!--通过有参构造形式注入依赖-->
    <bean id="student5" class="com.wrj.maventest.Spring.IOC.Pojo.Student">
        <!--id属性注入-->
        <constructor-arg name="id" value="11"/>
        <!--name属性注入-->
        <constructor-arg name="name" value="wrj"/>
    </bean>

有参构造是使用construct-arg标签

set方法注入依赖

给对象属性提供set方法


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

在配置文件中通过set方法赋值

<!--通过set方法注入依赖-->
    <bean id="student6" class="com.wrj.maventest.Spring.IOC.Pojo.Student">
        <property name="id" value="12"/>
        <property name="name" value="gy"/>
    </bean>

通过set方式使用的是property标签

注入的依赖也可以是自定义的类型

 <!--注入自定义类型-->
    <bean id="user" class="com.wrj.maventest.Spring.IOC.Pojo.User">
        <constructor-arg name="name" value="dd"/>
    </bean>
    <bean id="student7" class="com.wrj.maventest.Spring.IOC.Pojo.Student">
        <property name="id" value="12"/>
        <property name="name" value="gy"/>
        <!--value属性:将参数按照String类型解析
            ref属性:将参数解析成Spring中管理的对象的ID值
         -->
        <property name="user" value="user"/>
    </bean>

自定义类型也是要交给Spring管理,如何获取管理对象实例

使用ref属性来获取值,该ref会自动识别为Spring中对象的名称

使用value属性来获取值,Spring认为仅仅是一个字符串值

依赖也可以是集合类型

 <!--注入集合类型-->
    <bean id="student8" class="com.wrj.maventest.Spring.IOC.Pojo.Student">
        <!--注入list类型-->
        <property name="coursrName">
            <list>
                <value>语文</value>
                <value>数学</value>
                <value>英语</value>
            </list>
        </property>
        <!--注入Map类型-->
        <property name="coursrScore">
            <map>
                <entry key="语文" value="98"/>
                <entry key="数学" value="98"/>
                <entry key="英语" value="98"/>
            </map>
        </property>
    </bean>

基于注解形式注入依赖

@Value:注入普通类型属性

@Resource:注入对象类型

@Autowired:注入对象类型,默认按照类型注入

@Value:

该注解只能添加到普通类型上,@Value(“1”)注解中可以赋值完成对基础属性的依赖注入

@Component(value="student3")
//类似于XML配置文件 @Component类似于xml中的bean标签,value值类似于xml中的id属性
//@Repository
//@Service
//@Controller
public class Student {
    @Value("1")
    private Integer id;

@Resource:

该注解是注入对象类型

该注解是由java提供的,不是由Spring框架提供的,默认按照类的类型来查找并注入类

@Component(value="student3")
//类似于XML配置文件 @Component类似于xml中的bean标签,value值类似于xml中的id属性
public class Student {
   
    //自定义类型
    @Resource(name="user")
    private User user;

@Autowired:

该注解是注入对象类型的,是Spring框架提供的,按照名称来查找并注入类

@Component(value="student3")
public class Student {
  
    //自定义类型
    @Autowired
    private User user;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值