Spring Framework创建对象时间、初始化与销毁、IOC与DI结合的真正意义……

恍恍惚惚大二一年又过去了,马上要进入大三了,第一篇博客是刚上大二时候写的,到现在怎么感觉博客质量倒不如从前了,一直忙碌,却感觉没有忙出什么成效来,更博也少了,也只是贴上些代码,文字的描述更少了,感觉自己变得敷衍了,看来是应该反思反思这一年都干了什么。好吧,废话也不多说了,先贴上这篇最近学习spring的一点总结吧

1.什么是Spring,Spring是用来干嘛的?

Spring是一个非常活跃的开源框架;它是一个基于Core来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.

Spring以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”,这也就意味着你可以适当的时候安装或卸载Spring

 Spring就是一个容器

2.Spring的配置文件 

     默认情况下是applicationContext.xml文件。可以建立很多xml文件,工程中一般都是这样配置的。

3.Spring创建对象的时间

a.(在默认的情况下,启动Spring容器的时候创建对象)

好处:因为是在Spring容器启动的时候就创建对象,所以只要配置文件书写错误,在一开始的时候(web容器启动)就能发现错误

    b.懒加载lazy-init=”true” (在context.getBean时才要创建该对象)

   

<bean id=”” class=”” lazy-init=”true”></bean>

 

 

4.怎么证明Spring容器是单例的还是多例的

 

  a.我们可以写一个小例子,看地址,在Spring容器中的对象默认是单例的,因为对象是单例的,所以只要在类上声明一个属性,该属性中含有数据,那么该属性是全局的(这么做是很危险的),如下图

   <bean id="helloWorld" class="com.zkx.spring.scope.HelloWorld"></bean>

测试:

@Test
public void testScope_Default(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");

HelloWorld helloWorld2 = (HelloWorld)context.getBean("helloWorld");

System.out.println(helloWorld);

System.out.println(helloWorld2);

}

 

结果 com.zkx.spring.scope.HelloWorld@43763e0b

  com.zkx.spring.scope.HelloWorld@43763e0b

 证明了Spring容器中的对象默认是单例的

 

 

  b.如果说scope为”prototype”的时候,spring容器产生的对象就是多实例,无论lazy-init为什么值,都是在context.getBean时才要创建对象

  <bean id="helloWorld2" class="com.zkx.spring.scope.HelloWorld"

   scope="prototype"></bean>

 

测试结果是2个不同的地址,这里就不上测试代码了

 

注:在web开发中,通常把Srvice层和Dao层放进Spring容器中,整成单例的,这样你在浏览器输入一个url,一千次访问,一万次访问,Action调用Service,Service调用Dao,那么也只会产生一个Srvice层的对象和一个Dao层的对象,那么JVM销毁这些对象的压力大大减轻

 

5.什么是IOC?

IOC:Inversion of Control 控制反转

IOC即Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。

 

 

6.Spring的初始化和销毁

在applicationContext.xml文件中,加上下面的代码

<bean id="helloWorld" class="com.zkx.spring.initdestroy.HelloWorld"

init-method="init"

destroy-method="destroy"></bean>

初始化方:init-method

销毁方法 :destroy-method

 

public class HelloWorld {

public HelloWorld(){

System.out.println("aaaa");

}

public void hello(){

System.out.println("hello world");

}

public void init(){

System.out.println("init");

}

public void destroy(){

System.out.println("destroy");

}

}

 

 

@Test

public void testInitDestroy(){

ApplicationContext context = 

new ClassPathXmlApplicationContext("applicationContext.xml");

HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");

helloWorld.hello();
ClassPathXmlApplicationContext applicationContext = (ClassPathXmlApplicationContext) context;
applicationContext.close();//spring容器关闭

}

 

测试结果:

aaa

Init

Helloworld

destory

Spring容器关闭时,调用销毁方法,如果spring容器没有执行close方法,则不执行销毁方法,如果spring容器执行了close方法,在执行该方法之前要执行销毁方法;在构造方法之后,立刻执行init方法(destroy用途不是很大,init方法用途很多)

7.Spring的执行流程Spring Framework创建对象时间、初始化与销毁、IOC与DI结合的真正意义……

 

 

8.DI?

DI:Dependency Injection 依赖注入

 依赖注入简单的说就是给属性赋值,有2种注入的方法:

 a.使用构造器注入

使用xml的注入方式

   通过参数的顺序

<constructor-arg index="0">

      <value>张三</value>

</constructor-arg>

<constructor-arg index="1">

       <value>56</value>

 </constructor-arg>

 

  通过参数的类型

<constructor-arg type="java.lang.Integer">

              <value>56</value>

       </constructor-arg>

       <constructor-arg type="java.lang.String">

              <value>张三</value>

</constructor-arg>

 

b.使用属性set方法进行注入

使用xml的注入方式:

   简单Bean的注入

简单Bean包括两种类型:包装类型和String

<bean id="personService"   class="com.zkx.bean.impl.PersonServiceImpl">
<!-- 基本类型,string类型 -->
<property name="age" value="20"></property>
            <property name="name" value="张无忌"></property>    
</bean>
        <!--  引用其他Bean -->
               <bean id="person" class="com.zkx.bean.Person" />
               <bean id="personService"  class="com.zkx.bean.impl.PersonServiceImpl">
            <property name="person" ref="person" />

</bean>

 

 

 

 

9.IOC和DI结合的真正意义

 a.不完全的面向接口编程(客户端还得关心这个接口是由哪个类实现的)

如下图就是不完全的面向接口编程(WordDoment等类实现了Document接口,具体类的实现我就不列出来了),包括我以前那篇关于面向接口编程的博客,也是不完全的面向接口编程

@Test

public void testDocument_NOSpring(){

//为不完全的面向接口编程

Document document = new WordDocument();

DocumentManager documentManager = new DocumentManager();

documentManager.setDocument(document);

documentManager.readDocument();

documentManager.writeDocument();

}

 

   b把documentManager,wordDocument,excelDocument,pdfDocument放入到spring容器中

  

   

<bean id="documentManager" class="com.zkx.spring.iocdi.document.DocumentManager">

   <property name="document">

   <ref bean="wordDocument"/>

   </property>

   </bean>

   <bean id="wordDocument" class="com.zkx.spring.iocdi.document.WordDocument"></bean>

   <bean id="excelDocument" class="com.zkx.spring.iocdi.document.ExcelDocument"></bean>

   <bean id="pdfDocument" class="com.zkx.spring.iocdi.document.PDFDocument"></bean>

 

 

Java代码端的测试

@Test

public void testDocument_Spring(){

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

DocumentManager documentManager = (DocumentManager)context.getBean("documentManager");

documentManager.writeDocument();

documentManager.readDocument();

}

 

没有出现一个WordDocment等,也就是说java代码这头,只需要完全面向接口编程就行了,只需要关心Docment的API实现什么样的功能,至于说这个Docment具体是谁,我不关心

这就是IOC和DI结合的真正意义:

Java代码端完全的面向接口编程(现在很多容器都有这功能,都是模仿Spring的)

 

 

相关推荐