SpringIOC实现原理及获取方式总结

1.什么是Spring

Spring 被称为 J2EE 的春天,是一个开源的轻量级的 Java 开发框架, 具有控制反转(IOC)和面向切面(AOP)两大核心。Java Spring 框架通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

2.SpringIOC

2.1IOC(DI) - 控制反转(依赖注入)

所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周期的管理,而是在需要时由Spring框架提供,这个由spring框架管理对象创建和生命周期的机制称之为控制反转。而在创建对象的过程中Spring可以依据配置对对象的属性进行设置,这个过称之为依赖注入,也即DI。

IOC(Inversion of Control):控制反转

DI(Dependency Injection):依赖注入

IOC是一种思想,而DI是实现IOC的主要技术途径。

DI主要有两种注入方式,及Setter注入和构造器注入。

2.2IOC入门案例

a.创建一个java项目

spring并不是非要在javaweb环境下才可以使用,一个普通的java程序中也可以使用Spring。

b.导入Spring的lib目录下引入IOC相关的jar包

6个spring相关的包,一个其他包( commons-logging)

Jakarta  Commons-logging(JCL)是apache最早提供的日志的门面接口。提供简单的日志实现以及日志解耦功能。

将jar包Add as Library

idea是两级管理:在  模块下,可以有项目(一般开发选择Project Library)练习中则导入Module Library(给demo单独导包)

 c.创建Spring的配置文件

Spring采用xml文件作为配置文件,xml文件名字任意,但通常都取名为applicationContext.xml,通常将该文件放置在类加载的目录里下(src目录),方便后续使用。

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.xsd">

</beans>

 d.创建bean类,并在spring中进行配置交由spring来管理

public class Person {
    public void eat(){
        System.out.println("eating...");
    }
}
<?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="person" class="cn.ww.beans.Person"/>
</beans>

e.在程序中通过Spring容器获取对象并使用

package cn.ww.test;

import cn.ww.beans.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试类
 */
public class DemoTest {
    /**
     * 传统的通过创建对象调用方法
     */
    @Test
    public void test01(){
        //1.创建对象
        Person p = new Person();
        //2.调用方法
        p.eat();
    }

    /**
     * 通过spring获取对象并调用方法
     */
    @Test
    public void test02(){
        //1.初始化spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.通过spring容器获取bean,getBean中的person 为applicationContext 配置文件中的 bean的id
        Person p = (Person) context.getBean("person");
        //3.调用方法
        p.eat();
        //4.关闭spring容器
        ((ClassPathXmlApplicationContext)context).close();
    }
}

测试通过spring获取对象并调用对象方法成功 

 

3.IOC的实现原理

在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的<bean>标签时,会根据该标签中的class属性指定的类的全路径名,通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值值就是该对象。之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。

由此可以推测而知:

  • 默认情况下,多次获取同一个id的bean,得到的将是同一个对象。
  • 不可以配置多个id相同的bean
  • 可以配置多个id不同但class相同的bean

4.IOC获取对象的方式

通过context.getBean()方法获取bean时,可以通过如下两种方式获取:

  1. 传入id值
  2. 传入class类型

通过class方式获取bean时,如果同一个类配置过多个bean,则在获取时因为无法确定到底要获取哪个bean会抛出异常。

而id是唯一的,不存在这样的问题,所以建议大家尽量使用id获取bean。

/**

 * 获取对象的方式

 *  通过id获取bean

 *      如果找不到,抛异常NoSuchBeanDefinitionException

 *      如果找到唯一的,返回对象

 *      因为id不重复,不可能找到多个

 *  通过class获取bean

 *      如果找不到,抛出异常NoSuchBeanDefinitionException

 *      如果找到唯一,返回对象

 *      如果找到多个,抛出异常NoUniqueBeanDefinitionException

 */

@Test

public void  test04(){

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

 

    //获取对象方式1:通过id获取

    //Person p = (Person)context.getBean("person");

    //p.eat();

    //p.say();

    //获取对象方式2:通过class获取

    Person p = context.getBean(Person.class);

    p.eat();

    p.say();

 

    ((ClassPathXmlApplicationContext)context).close();

}

SpringIOC在通过class获取bean时,如果找不到该类型的bean还会去检查是否存在该类型的子孙类型的bean,如果有则返回,如果找不到或找到多个则抛出异常。这符合java面向对象思想中的多态的特性。

@Test

public void test02() {

//1.初始化spring容器

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

//2.获取Bean

JavaTeacher jt = (JavaTeacher) context.getBean(Teacher.class);

System.out.println(jt);

}
 

5.别名标签

 在 Spring中提供了别名标签<alias>可以为配置的<bean>起一个别名,要注意的是这仅仅是对指定的<bean>起的一个额外的名字,并不会额外的创建对象存入map。(当类名较长时,可以取别名,方便调用,简化代码)

格式:<alias name="要起别名的bean的id"  alias="要指定的别名"/>

如下图,在applicationContext配置文件中配置person的别名为pre

在获取bean时可以直接通过别名来获取

测试结果正常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值