Spring——IOC

IoC即控制反转,简单的说就是以前你要使用一个对象,需要在代码中new一个出来,而现在你要使用,IoC容器会帮你new出来。可以这样理解,以前你是独自一个人,想要使用什么都要自己动手获得后再使用,而现在你有了一个保姆,你想要用什么的时候,直接和保姆说一声,它就会帮你准备好。通过IoC能大大降低耦合度。


依赖注入的三种方式:

  1. 构造器注入:构造器注入即是将依赖的对象作为构造函数的参数。这种注入方式的优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用。缺点就是,当依赖对象比较多的时候,构造方法的参数列表会比较长。而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。

     People(PeopleWork pw,PeopleStudy ps){
        this.pw=pw;
        this.ps=ps
    }
    

     

     

  1. Setter注入:对于javabean来说,是通过setXXXgetXXX方法来进行属性的访问的,setter注入和这种差不多。。因为方法可以命名,所以setter方法注入在描述性上要比构造方法注入好一些。另外,setter方法可以被继承,允许设置默认值。

    privatePeopleWork pw;
    private PeopleStudy ps;
    public void setPeopleWork(PeopleWork pw){
        this.pw=pw;
    }
    
    Public void setPeopleStudy(PeopleStudy ps){
        this.ps=ps;
    }
    

     

     

  1. 接口注入: -- 很遗憾...貌似没接触过...


IoC Service Provider的职责

IoC Service Provider的职责相对来说比较简单,主要有两个:业务对象的构建管理和业务对象间的依赖绑定。

 

SpringIoC容器

Spring提供了两种容器类型:

1IoC容器——BeanFactory

基础类型IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IoC容器选择。

2IoC容器——ApplicationContext

ApplicationContextBeanFactory的基础上构建,是相对比较高级的容器实现,除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。所以,相对于BeanFactory来说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中,ApplicationContext类型的容器是比较合适的选择。

 

 

BeanFactoryApplication之间的关系:

 

 

IoC Service Provider 如何管理对象间的依赖关系

 

  1. 直接编码方式:

  2. 配置文件方式:

 


 

接下来以BeanFactory来讲的对象注册与依赖绑定方式的内容同样适用于ApplicationContext,但是ApplicationContext能用的BeanFactory就不一定了。

 


 

  1. 直接编码方式:实际上不管是什么方式,最终都是到达编码这一个步骤的。这一步骤可以简单的描述为:定义bean->注册bean->注入依赖的bean

 

Man.java

 public class Man{
 public void say() {
    System.out.println("I am a man");
 }
}

 

 

 

 

 

PService.java

 public class PService {

public PService(Man man) {

this.man = man;

}
private Man man;
public Man getMan() {
return man;
}

public void setMan(Man man) {
this.man = man;
}

public void say(){
man.say();
}

}

 

 MyTest.java

 Import ....省略...

public class MyTest {

public static void main(String[] args) {

DefaultListableBeanFactory beanRegistry=new DefaultListableBeanFactory();

BeanFactory beanfactory=(BeanFactory)bindViaCode(beanRegistry);

PService pservice=(PService)beanfactory.getBean("pservice");

pservice.say();

}

public static BeanFactory bindViaCode(BeanDefinitionRegistry registry){

AbstractBeanDefinition man=new RootBeanDefinition(Man.class);

AbstractBeanDefinition pservice=new RootBeanDefinition(PService.class);

//将bean注册到容器中...

registry.registerBeanDefinition("man",man);

registry.registerBeanDefinition("pservice",pservice);

//通过构造器注入

ConstructorArgumentValues argValues=new ConstructorArgumentValues();

argValues.addIndexedArgumentValue(0, man);

pservice.setConstructorArgumentValues(argValues);

//通过setter方式注入

MutablePropertyValues propertyValues=new MutablePropertyValues();

propertyValues.addPropertyValue(new PropertyValue("man",man));

pservice.setPropertyValues(propertyValues);

return (BeanFactory)registry;

}

}

 

 

 

 

 

 

  1. 配置文件方式:

 

配置文件格式包括:Properties文件和XML文件。实际上配置文件的方式也是和编码方式息息相关的,只不过多了些步骤。对于配置文件的方式来说,是通过BeanDefinitionReader接口的实现类(对于Properties文件来说是PropertiesBeanDefinitionReader类,对于XML文件来说是XmlBeanDefinitionReader)来解析配置文件的信息,然后将解析出来的信息按照编码方式的步骤进行。(不过大家应该都用的是xml...至少我是没用过Properties的)

 

Beans.xml

 

 <bean id="man" class="Man" />

<bean id="pservice" class="PService">

<property name="man" ref="man"/>

</bean>

 

 

MyTest1.java

 public class MyTest1 {

public static void main(String[] args) {

BeanFactory beanfactory=new XmlBeanFactory(new ClassPathResource("beans.xml"));

PService pservice=(PService)beanfactory.getBean("pservice");

pservice.say();

}

}

 

 3、注解方式

 

Man.java

 @Component

public class Man{

public void say() {

System.out.println("I am a man");

}

}

 

 

 

 

PService.java

 

 @Component

public class PService {

public PService(Man man) {

this.man = man;

}

public PService() {

super();

}

@Autowired

private Man man;

public Man getMan() {

return man;

}

public void setMan(Man man) {

this.man = man;

}

public void say(){

man.say();

}

}

 

 

 

 

 

Beans.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-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="org.pig.test"/>

</beans> 

 

 

<context:component-scan/>会到指定的包(package)下面扫描标注有@Component的类,如果

 

找到,则将它们添加到容器进行管理,并根据它们所标注的@Autowired为这些类注入符合条件的依

 

赖对象。

 

 

Mytest2.java

 public class MyTest2 {

public static void main(String[] args) {

ApplicationContext app=new ClassPathXmlApplicationContext("beans.xml");

PService p=(PService)app.getBean("PService");

p.say();

}

}

 

 

 

 

 

 

 

posted @ 2013-12-30 17:12  红尘眷恋  阅读(252)  评论(0编辑  收藏  举报