我和春天有个约会(一)

来源:互联网 发布:sql语句括号的用法 编辑:程序博客网 时间:2024/04/20 10:21

 我和春天有个约会(一)

长夜漫漫,无心睡眠,于是打开电脑,我来到她身边,她的名字叫春天。为她建了一个小屋,叫做Eclipse;为她点了一盏小灯,叫做Spring IDE;为她准备的《春江花月夜》在耳边静静流淌,带着爱情指南《Spring2.0技术手册》,我们的耳鬓厮磨开始了。
验证BeanScope
多变的她……
Spring2.0配置文件中bean的Scope分为Singleton和Prototype两种。Scope设为Singleton的bean每次通过BeanFactory/ApplicationContext创建得到的对象都是同一个对象,而Scope设为Prototype的bean每次创建都得到不同的对象,验证一把,非常easy。
定义两个类:
public class BeanScopePrototype {
    
public BeanScopePrototype() {
    }

}


public class BeanScopeSingleton {    
    
public BeanScopeSingleton() {        
    }

}

 
 
在配置文件中设定它们的scope:
<bean id="singleton_scope" class="my.BeanScopeSingleton"/>
    
<bean id="prototype_scope" class="onlyfun.my.BeanScopePrototype"
     scope
="prototype"/>
 
singleton_scope而言,默认配置是Singleton,所以无须专门设定。
验证程序为:
public static void main(String[] args) {
        Resource rs 
= new ClassPathResource("beans-config.xml");
        BeanFactory factory 
= new XmlBeanFactory(rs);
        BeanScopeSingleton bean_singleton1 
=
                        (BeanScopeSingleton) factory.getBean("singleton_scope");
        BeanScopeSingleton bean_singleton2 
= 
                        (BeanScopeSingleton) factory.getBean("singleton_scope");
        
if (bean_singleton1 == bean_singleton2) {
                  System.out.println(
"Singleton acts!");
        }
 else {
                  System.out.println(
"Singleton doesn't act");
        }


        BeanScopePrototype bean_prototype1 
= (BeanScopePrototype) factory.getBean("prototype_scope");
        BeanScopePrototype bean_prototype2 
= (BeanScopePrototype) factory.getBean("prototype_scope");
        
if(bean_prototype1 != bean_prototype2) {
                 System.out.println(
"Prototype acts!");
        }
 else {
                 System.out.println(
"Prototype doesn't act");
        }

    }

 
 
结果自然都“acts”了。
Design Pattern里说Singleton是指内存中只存在某个对象的一个实例(林先生说是对每个ClassLoader所载入的类产生一个实例……和ClassLoader有啥关系??不太理解,Who can tell me?)。
这里的Singleton则是说每个IoC容器(BeanFactory/ApplicationContext)维持一个Bean实例。每个容器吗?
BeanFactory factory2 = new XmlBeanFactory(rs);
       BeanScopeSingleton bean_singleton3 
=
                                        (BeanScopeSingleton) factory2.getBean("singleton_scope");
        
if (bean_singleton1 != bean_singleton3) {
                System.out.println(
"Okey");
        }
 else {
                System.out.println(
"What's wrong?");
        }

 
Okey,结果就是Okey。
 
 
Bean的生命周期
她幽幽的向我诉说她的前世,今生……
 
这个地方总是很枯燥,于是我不得不亲自动手。
首先定义一个类叫做BeanLifeCycle它实现了BeanNameAware, BeanFactoryAware, DisposableBean, InitializingBean四个接口,这是为了将bean对象生命周期演化所涉及到的过程尽量展示出来,与之对应的方法则是setBeanNamesetBeanFactorydestroyafterPropertiesSet。前两者用意目前不是很明朗,后两者分别用于bean的创建和消亡。
定义了方法init_beandestory_bean,它们写进了配置文件,发生于bean的创建和消亡。
定义了构造函数。
定义了实例方法do_somethiing
 
public class BeanLifeCycle implements BeanNameAware, BeanFactoryAware,
      DisposableBean, InitializingBean 
{
      
public BeanLifeCycle() {
              System.out.println(
"Constructor...");
          }


      
public void setBeanName(String name) {
               System.out.println(
" ***setBeanName:" + name);
          }


      
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
             System.out.println(
" ***setBeanFactory:" + beanFactory.toString());
         }


    
public void init_bean() {
               System.out.println(
" ***init_bean");
        }


    
public void destroy() throws Exception {
        System.out.println(
" ***destory");

    }


    
public void afterPropertiesSet() throws Exception {
              System.out.println(
" ***afterPropertiesSet");        
       }

    
    
public void destory_bean() {
            System.out.println(
" ***destory_bean");
       }


    
public void do_somethiing() {
               System.out.println(
" ***Do something...finally");
        }

}

 
相关配置:
<bean id="lifecycle" class="onlyfun.caterpillar.BeanLifeCycle"
        init-method
="init_bean" destroy-method="destory_bean" />
 
跑一把瞅瞅:
Constructor...
 
***setBeanName:lifecycle
 
***setBeanFactory:org.springframework.beans.factory.xml.XmlBeanFactory@1e4f7c2: defining beans [writer,singleton_scope,prototype_scope,lifecycle,business]; root of factory hierarchy
 
***afterPropertiesSet
 
***init_bean
 
***Do something...finally
哦,原来是这个样子啊:首先构造;然后setBeanName,其参数就是配置文件中的bean id,接下来setBeanFactory,其参数就是BeanFactory的具体实现;然后初始化,有两种方式,来自于接口InitializingBeanafterPropertiesSet,以及来自于配置文件的init_bean,两种方式可互相替换,此时教Spring的老师总告诫我们,要提高可移植性避免耦合到Spring中去就采用init_bean方式,这样就不用绑上Spring接口(话虽不错,可总觉得直接移植的场合很少)。
Then…终于到我的逻辑:do_something
最后destory_beandestroy的执行并没有发生,看来bean的销毁过程还不清楚,留待以后。
ApplicationContext管理bean周期的方式大致相当,稍有不同,庐山真面目此时还看不透,不纠缠了,撤。
 
Bean的依赖设置之Lookup Method Injection
两情若是久长时,又岂在朝朝暮暮……
IoC是Spring的两大支柱之一,为对象解耦合从而提升系统设计质量提供一套框架和思想,而所谓Lookup-Method-Injection则是看来比较花哨的一个手法,暂且不去估量其实用性,玩味一番,实在是将依赖注入推向了新的境界。
public abstract class MessageManager {
                
public void display() {
                        Message message 
= createMessage();
                        System.out.println(message);
                     }

    
                    
protected abstract Message createMessage();
             }

 
这里需要注入的已不是某个内部属性,而是一个抽象方法所返回的对象,该对象的类定义为
public class Message {
    
private String sysMessage;

 
public Message() {
      sysMessage 
= "系统消息: " + new Date().toString();
    }


  
public String toString() {
       
return sysMessage;
    }

}

 
看来并不能直接联系的两个类就通过配置文件联系在了一起,该配置定义了lookup-method属性:
<bean id="sysMessage" 
          class
="onlyfun.caterpillar.Message" scope="prototype"/>

 
<bean id="messageManager" 
          class
="onlyfun.caterpillar.MessageManager">
        
<lookup-method name="createMessage" bean="sysMessage"/>
</bean>
 
林先生说“Spring中还提供了一个更不常用的Arbitrary method replacement”,可见这套Lookup-Method-Injection也不受广大人民群众的待见。
null
原创粉丝点击