【Spring]】IOC应用【1】 - 创建对象与DI的初接触

IOC概念:

控制反转:将对象创建和对象之间的调用从程序员手上交给Spring IOC容器进行管理
目的是为了降低程序的耦合度。

何谓耦合度?

按我自己的理解,耦合度高的结果是:维护成本高
例如一个场景中,耦合度高的代码在进行代码修改的时候,我需要在所有使用到这个类的地方全部修改。表现出,一处修改,全部修改。这显然是一个灾难

那耦合度是可以为0吗?

答案是否定的。如果一个程序完全没有耦合度,那他们之间就没有合作关系了。也就是说:类之间失去了协调工作的能力
但是我们可以把他降低到最低限度,这个降低的过程称为:解耦

所以我们的目标是:高内聚,低耦合

高内聚是指:在符合设计模式单一责任原则的基础上,模块只完成自己的任务,不干预其他的模块。
(这里会引出很多分支概念,如单一责任原则和设计模式,这里就不展开了)

IOC容器可以存放多个Bean,而Bean的注入又有两种实现方法

实现:

  1. XML
  2. 注解

应用场景

当一个在一个类中的一个方法,需要调用到另外一个对象中的方法。传统的方法是在方法内部new 一个对象出来,然后通过这个对象调用目的方法。而这种耦合度过于高。所以才需要IOC来降低程序的耦合度。
如代码段

class Book{
	public getBook(){
	...
	}
}
class BookStore{
	public void add(){
		Book book= new Book();
		book.getBook();
		...
	}	
}

工厂模式

目的:为了降低传统模式的耦合度
加入一个工厂类

class BookFactory{
	public static Book getBook(){
		return new Book();
	}
}
class BookStore{
	public void add(){
		Book book= new Book();
		BookFactory.getBook();
		...
	}	
}
//反射创建对象
class BookFactory{
	public static Book getBook() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        String className="Day6.Bean.Book";
        Class myClass=Class.forName(className);
        Book o = (Book)myClass.newInstance();
        return o;
    }
}

降低了Book与BookStore之间的耦合度。但是耦合度就转移到工厂上了。

Spring实现IOC容器的方式:


1. ApplicationContext


2. BeanFactory(不常用)


两个都能实现加载配置文件。
但是BeanFactory一般是用在Spring内部,开发人员一般使用ApplicationContext。

ApplicationContext是BeanFactory的一个子接口,拥有更多的功能

BeanFactory在执行

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

的时候不会创建对象,而是在getBean的时候才会获取对象(懒加载

ApplicationContext则会在

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

的时候创建对象(饿汉式)

Bean管理操作

Bean管理操作指的是两个,一个是Spring创建对象,一个是Spring注入属性
而实现Bean管理操作的方式有两种,一个是基于XML配置文件方式实现,一个是基于注解方式实现

**

本文先说基于XML配置文件下的Bean管理操作:

在中有很多属性,例如class,id
这两个属性是bean中很重要的属性。
本文先只说这两个属性

这里提一下:name属性
name属性的用法与id属性基本相同。
但是name能加特殊符号,id则不能
name属性的创立是为了struts1框架,现在几乎不用了

创建对象:

<bean id="book" class="Day6.Bean.Book">
       <property name="name" value="congcongcong"/>
</bean>

其中,class表示指向这个创建对象的类路径,id表示这个类的id,以方便后续getBean的时候拿到对象就是根据ID去拿到的。注意:这里默认使用无参构造,所以如果类中没有无参构造,没有用constructor,会报错。这里是一个易错点
主函数:

public class Main {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("Note.xml");
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
        book.add();
    }
}

运行截图
在这里插入图片描述

通过这个例子可以知道,我们通过加载配置文件去创建对象,把创建对象的控制权反转了,不再是通过修改源代码来控制创建对象,而是通过修改配置文件去创建对象。
示例中并没有出现new

DI(依赖注入(dependency injection)):

set方法注入属性
通过上述的例子也可知道,通过

<property name="name" value="congcongcong"/>

就能注入名字为name的属性,值为
而这个操作的前提是:

  1. 在对应路径"Day6.Bean.Book"类中必须要有一个setName方法。
  2. 在对应路径的8"Day6.Bean.Book"类中必须要有无参构造的方法。

原因

  1. 因为setProperty在set后的属性名才可被识别为一个Bean的属性
  2. 因为Spring底层默认使用无参构造方法创建对象,所以只有创建对象之后才能用对其注入,但是也不一定,后续有能够使Springg使用有参构造方法创建对象的方法。

否则注入失败。

有参构造方法注入

<bean id="book" class="Day6.Bean.Book">
     <constructor-arg name="name" value="congcongcong"/>
</bean>

总结:

  1. 使用set方法注入值使用property
  2. 使用有参构造函数注入使用constructor-arg
  3. 有参构造和set注入不能同时使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值