??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美一区二区三区四区五区六区,国产精品一区毛片,国产精品美女一区二区http://www.aygfsteel.com/pucca/zh-cnMon, 19 May 2025 02:42:10 GMTMon, 19 May 2025 02:42:10 GMT60威客地图Qhttp://www.witkeymap.comhttp://www.aygfsteel.com/pucca/archive/2007/11/21/162059.htmlpuccu的小?/dc:creator>puccu的小?/author>Wed, 21 Nov 2007 04:18:00 GMThttp://www.aygfsteel.com/pucca/archive/2007/11/21/162059.htmlhttp://www.aygfsteel.com/pucca/comments/162059.htmlhttp://www.aygfsteel.com/pucca/archive/2007/11/21/162059.html#Feedback1http://www.aygfsteel.com/pucca/comments/commentRss/162059.htmlhttp://www.aygfsteel.com/pucca/services/trackbacks/162059.html
威客地图 http://www.witkeymap.com

]]>
理解Spring[转]http://www.aygfsteel.com/pucca/archive/2006/08/30/66640.htmlpuccu的小?/dc:creator>puccu的小?/author>Wed, 30 Aug 2006 04:40:00 GMThttp://www.aygfsteel.com/pucca/archive/2006/08/30/66640.htmlhttp://www.aygfsteel.com/pucca/comments/66640.htmlhttp://www.aygfsteel.com/pucca/archive/2006/08/30/66640.html#Feedback0http://www.aygfsteel.com/pucca/comments/commentRss/66640.htmlhttp://www.aygfsteel.com/pucca/services/trackbacks/66640.html  

最q研ISpringQ她包含的编E思想让我耳目一新。所以写下这入门文章供新手参考。我不是什么Spring的资qIh员,我只是现学现卖。所以文章也只能是肤单薄,错误隑օQ还误谅?br />一、  ?Spring诞生
Spring是一个开源框Ӟ目前在开源社区的人气很旺Q被认ؓ是最有前途的开源框架之一。她是由Rod Johnson创徏的,她的诞生是ؓ了简化企业pȝ的开发。说道Spring׃得不说EJBQ因为Spring在某U意义上是EJB的替代品Q她是一U轻量的容器。用qEJB的h都知道EJB很复杂,Z一个简单的功能你不得不~写多个Java文g和部|文Ӟ他是一U重量的容器。也怽不了解EJBQ你可能对“轻Q重Q量U”和“容器”比较陌生,那么q里我简单介l一下?br />1、什么是容器
“容器”,q个概念困扰我好久。从学习Tomcat开始就一直对此感到困惑。感性的来讲Q容器就是可以用来装东西的物品。那么在~程领域是指用来装对象QOO的思想Q如果你qOO都不了解Q徏议你d习OO先)的对象。然而这个对象比较特别,它不仅要容纳其他对象Q还要维护各个对象之间的关系。这么讲可能q是太抽象,来看一个简单的例子Q?br />代码片断1Q?/font>

public class Container 
{
    public void init()
    {
    Speaker s = new Speaker();
    Greeting g = new Greeting(s);
    }
}

可以看到q里的Containerc(容器Q在初始化的时候会生成一个Speaker对象和一个Greeting对象Qƈ且维持了它们的关p,当系l要用这些对象的时候,直接问容器要可以了。这是容器最基本的功能,l护pȝ中的实例Q对象)。如果到q里你还是感到模p的话,别担心,我后面还会有相关的解释?/font>

2、轻量与重量
所谓“重量”是相对于“轻量”来讲的Q也可以说“轻量”是相对于重量来讲的。在Spring出现之前Q企业开发一般都采用EJBQ因为它提供的事务管理,声明式事务支持,持久化,分布计算{等都“简化”了企业U应用的开发。我q里的“简化”打了双引号Q因是相对的。重量容器是一U入侵式的,也就是说你要用EJB提供的功能就必须在你的代码中体现出来你用的是EJBQ比如承一个接口,声明一个成员变量。这样就把你的代码绑定在EJB技术上了,而且EJB需要JBOSSq样的容器支持,所以称之ؓ“重量”?br />相对而言“轻量”就是非入R式的Q用Spring开发的pȝ中的cM需要依赖Spring中的c,不需要容器支持(当然Spring本n是一个容器)Q而且Spring的大和q行开支都很微量。一般来_如果pȝ不需要分布计或者声明式事务支持那么Spring是一个更好的选择?/font>

二、  ?几个核心概念
在我看来Spring的核心就是两个概念,反向控制QIoCQ,面向切面~程QAOPQ。还有一个相关的概念是POJOQ我也会略带介绍?br />1、POJO
我所看到q的POJO全称有两个,Plain Ordinary Java ObjectQPlain Old Java ObjectQ两个差不多Q意思都是普通的Javac,所以也不用ȝ谁对谁错。POJO可以看做是简单的JavaBeanQ具有一pdGetterQSetterҎ的类Q。严格区分这里面的概忉|有太大意义,了解一下就行?br />2、  ?IoC
IoC的全U是Inversion of ControlQ中文翻译反向控制或者逆向控制。这里的反向是相对EJB来讲的。EJB使用JNDI来查N要的对象Q是d的,而Spring是把依赖的对象注入给相应的类Q这里涉及到另外一个概念“依赖注入”,E后解释Q,是被动的Q所以称之ؓ“反向”。先看一D代码,q里的区别就很容易理解了?br />代码片段2Q?/font>

public void greet()
{
Speaker s = new Speaker();
s.sayHello();
}

代码片段3Q?/font>

public void greet()
{
Speaker s = (Speaker)context.lookup("ejb/Speaker");
s.sayHello();
}

代码片段4Q?/font>

public class Greeting 
{
    public Speaker s;
    public Greeting(Speaker s)
    {
        this.s = s;
    }
    public void greet()
    {
        s.sayHello();
    }
}

我们可以Ҏ一下这三段代码。其中片D?是不用容器的~码Q片D?是EJB~码Q片D?是Spring~码。结合代码片D?Q你能看出来Spring~码的优之处吗Q也怽会觉得Spring的编码是最复杂的。不q没关系Q我在后面会解释Spring~码的好处?br />q里我想先解释一下“依赖注入”。根据我l的例子可以看出QGreetingcM赖SpeakercR片D?和片D?都是d的去获取SpeakerQ虽然获取的方式不同。但是片D?q没有去获取或者实例化Speakerc,而是在greeting函数中直接用了s。你也许很容易就发现了,在构造函C有一个s被注入(可能你^时用的是Q传入)。在哪里注入的呢Q请回头看一下代码片D?Q这是使用容器的好处,由容器来l护各个cM间的依赖关系Q一般通过Setter来注入依赖,而不是构造函敎ͼ我这里是Z化示例代码)。Greetingq不需要关心Speaker是哪里来的或是从哪里获得SpeakerQ只需要关注自己分内的事情Q也是让Speaker说一句问候的话?br />3、  ?AOP
AOP全称是Aspect-Oriented ProgrammingQ中文翻译是面向斚w的编E或者面向切面的~程。你应该熟悉面向q程的编E,面向对象的编E,但是面向切面的编E你也许是第一ơ听说。其实这些概念听h很玄Q说到底也就是一句话的事情?br />现在的系l往往减小模块之间的耦合度,AOP技术就是用来帮助实现这一目标的。D例来_假如上文的Greetingpȝ含有日志模块Q安全模块,事务理模块Q那么每一ơgreet的时候,都会有这三个模块参与Q以日志模块ZQ每ơgreet之后Q都要记录下greet的内宏V而对于Speaker或者Greeting对象来说Q它们ƈ不知道自q行ؓ被记录下来了Q它们还是像以前一L工作Qƈ没有M区别。只是容器控制了日志行ؓ。如果这里你有点p涂Q没关系Q等讲到具体Spring配置和实现的时候你明白了?br />假如我们现在为Greetingpȝ加入一个Valediction功能Q那么AOP模式的系l结构如下:
G|RET|TIN|G
V|ALE|DIT|ION
|   |   |
日志 安全 事务

q些模块是诏I在整个pȝ中的Qؓpȝ的不同的功能提供服务Q可以称每个模块是一个“切面”。其实“切面”是一U抽象,把系l不同部分的公共行ؓ抽取出来形成一个独立的模块Qƈ且在适当的地方(也就是切入点Q后文会解释Q把q些被抽取出来的功能再插入系l的不同部分?br />从某U角度上来讲“切面”是一个非常Ş象的描述Q它好像在系l的功能之上横切一刀Q要惌pȝ的功能l,必dq了q个切面。这些切面监视ƈ拦截pȝ的行为,在某些(被指定的Q行为执行之前或之后执行一些附加的dQ比如记录日志)。而系l的功能程Q比如GreetingQƈ不知道这些切面的存在Q更不依赖于q些切面Q这样就降低了系l模块之间的耦合度?/font>

三、  ?Spring初体?br />q一节我用一个具体的例子GreetingQ来说明使用Spring开发的一般流E和ҎQ以及Spring配置文g的写法?br />首先创徏一个Speakerc,你可以把q个cȝ做是POJO?br />代码片段5Q?/font>

public class Speaker 
{
    public void sayHello()
    {
        System.out.println("Hello!");
    }
}
再创Z个GreetingcR?br />代码片段6Q?/font>

public class Greeting 
{
    private Speaker speaker;
    public void setSpeaker(Speaker speaker)
    {
        this.speaker = speaker;
    }
    public void greet()
    {
        speaker.sayHello();
    }
}

然后要创Z个Spring的配|文件把q两个类兌h?br />代码片段7QapplicationContext.xmlQ:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
    "
http://www.springframework.org/dtd/spring-beans.dtd ">

<beans>
    <bean id="Speaker" class="Speaker"></bean>
    <bean id="Greeting" class="Greeting">
        <property name="speaker">
            <ref bean="Speaker"/>
        </property>
    </bean>
</beans>

要用Spring Framework必须把Spring的包加入到Classpath中,我用的是Eclipse+MyEclipseQ这些工作是自动完成的。推荐用Spring的配|文件编辑器来编辑,U手工编写很Ҏ出错。我先分析一下这个xml文g的结构,然后再做试。从<beans>节点开始,先声明了两个<bean>Q第二个bean有一个speaker属性(propertyQ要求被注入Q注入的内容是另外一个bean Speaker。这里的命名是符合JavaBean规范的,也就是说如果是speaker属性,那么Spring容器׃调用setSpeaker()来注入这个属性?lt;ref>是reference的意思,表示引用另外一个bean?br />下面看一D늮单的试代码Q?br />代码片段8Q?/font>

public static void main(String[] args) 
{
        ApplicationContext context = 
            New ClassPathXmlApplicationContext("applicationContext.xml");
        Greeting greeting = (Greeting)context.getBean("Greeting");
        greeting.greet();
}

q段代码很简单,如果你上文都看懂了,那么q里应该没有问题。值得注意的是Spring有两U方式来创徏容器Q我们不再用上文我们自己~写的ContainerQ,一U是ApplicationContextQ另外一U是BeanFactory。ApplicationContext更强大一些,而且使用上两者没有太大区别,所以一般说来都用ApplicationContext。Spring容器帮助我们l护我们在配|文件中声明的Bean以及它们之间的依赖关p,我们的Bean只需要关注自q核心业务?/font>

四、  ?面向接口的编E?br />看了q么多,也许你ƈ没有觉得Springl开发带来了很多便利。那是因为我丄例子q不能突出Spring的优之处,接下来我通过接口~程来体现Spring的强大?br />假如现在要求扩展Greeting的功能,要让Speaker用不同的语言来问候,也就是说有不同的SpeakerQ比如ChineseSpeaker, EnglishSpeaker。那么对上文提到的三U编码方式(代码片段2??Q分别加以修改,你会发现很麻烦。假如下ơ又要加入一个西班牙语,又得重复力_。很自然的会考虑C用一个ISpeaker接口来简化工?Q更改后的代码如下(q里没有列出接口的相关代码,我想你应该明白怎么写)Q       ?

代码片段9Q?/font>

public void greet()
{
ISpeaker s = new ChineseSpeaker();
s.sayHello();
}

代码片段10Q?/font>

public void greet()
{
ISpeaker s = (ISpeaker)context.lookup("ejb/ChineseSpeaker");
s.sayHello();
}

代码片段11Q?/font>

public class Greeting 
{
    public ISpeaker s;
    public Greet(ISpeaker s)
    {
        this.s = s;
    }
    public void greet()
    {
        s.sayHello();
    }
}
Ҏ三段代码Q你会发玎ͼW一U方法还是把具体的Speaker编码到代码中了Q第二中ҎE微好一点,但是没有本质改变Q而第三种Ҏ׃一样了Q代码中q没有关于具体Speaker的信息。也是_如果下次q有什么改动的话,W三U方法的GreetingcL不需要修改,~译的。根据上文Spring的用介l,只需要改动xml文gplGreeting注入不同的Speaker了,q样代码的扩展性是不是提高了很多?
关于Spring的接口编E还有很多东西可以去挖掘Q后文还会提到有关Spring Proxy的接口编E,我这里先介绍q么多,有兴话可以去google更多的资料?/font>

五、  ?应用Spring中的切面
Spring生来支持AOPQ首先来看几个概念:
1、  ?切面QAspectQ:切面是系l中抽象出来的的某一个功能模块,上文已经有过介绍Q这里不再多说?br />2、  ?通知QAdviceQ:通知是切面的具体实现。也是说你的切面要完成什么功能,具体怎么做就是在通知里面完成的。这个名UC乎有点让解,{后面看了代码就明白了?br />3、  ?切入点(PointcutQ:切入点定义了通知应该应用到系l的哪些地方。Spring只能控制到方法(有的AOP框架可以控制到属性)Q也是说你能在Ҏ调用之前或者之后选择切入Q执行额外的操作?br />4、  ?目标对象QTargetQ:目标对象是被通知的对象。它可以是Q何类Q包括你自己~写的或者第三方cR有了AOP以后Q目标对象就只需要关注自q核心业务Q其他的功能Q比如日志,qAOP框架支持完成?br />5、  ?代理QProxyQ:单的Ԍ代理是通知应用到目标对象后产生的对象。Spring在运行时会给每个目标对象生成一个代理对象,以后所有对目标对象的操作都会通过代理对象来完成。只有这样通知才可能切入目标对象。对pȝ的其他部分来_q个q程是透明的,也就是看h跟没用代理一栗?br />我ؓ了简化,只介l这5个概c通过q几个概念应该能够理解Spring的切面编E了。如果需要深入了解Spring AOP的话再去学习其他概念也很快的?br />下面通过一个实际的例子来说明Spring的切面编E。l上文Greeting的例子,我们惛_Speaker每次说话之前记录Speaker被调用了?br />首先创徏一个LogAdvicec:
代码片段12Q?/font>

public class LogAdvice implements MethodBeforeAdvice 
{
    public void before(Method arg0, Object[] arg1, Object arg2)throws Throwable 
    {
        System.out.println("Speaker called!");
    }
}
q里涉及C个类QMethodBeforeAdviceQ这个类是Springcd提供的,cM的还有AfterReturningAdvice{等Q从字面p理解它们的含义。先不急着理解q个c,我稍后解释。我们l看如何把这个类应用到我们的pȝ中去?br />代码片段13Q?/font>

<beans>
    <bean id="Speaker" class="Speaker"/>
    <bean id="Greeting" class="Greeting">
        <property name="speaker">
            <ref bean="SpeakerProxy"/>
        </property>
    </bean>
    <bean id="LogAdvice" class="LogAdvice"/>
    <bean id="SpeakerProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>ISpeaker</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>LogAdvice</value>
            </list>
        </property>
        <property name="target">
            <ref local="Speaker"/>
        </property>
    </bean>
</beans>

可以看到我们的配|文件中多了两个beanQ一个LogAdviceQ另外一个SpeakerProxy。LogAdvice很简单。我着重分析一下SpeakerProxy。这个Bean实际上是由Spring提供的ProxyFactoryBean实现。下面定义了三个依赖注入的属性?br />1、  ?proxyInterfactesQ这个属性定义了q个Proxy要实现哪些接口,可以是一个,也可以是多个Q多个的话,要用list标签Q。我前面讲过Proxy是在q行是动态创建的Q那么这个属性就告诉Spring创徏q个Proxy的时候实现哪些接口?br />2、  ?interceptorNamesQ这个属性定义了Proxy被切入了哪些通知Q这里只有一个LogAdvice?br />3、  ?targetQ这个属性定义了被代理的对象。在q个例子中target是Speaker?br />q样的定义实际上U束了被代理的对象必dC个接口,q与上文讲的面向接口的编E有点类伹{其实可以这L解,接口的定义可以让pȝ的其他部分不受媄响,以前用ISpeaker接口来调用,现在加入了Proxyq是一L。但实际上内容已l不一样了Q以前是SpeakerQ现在是一个Proxy。而target属性让proxy知道具体的方法实现在哪里。Proxy可以看作是target的一个包装。当然Springq没有强制要求用接口Q通过CGLIBQ一个高效的代码生成开源类库)也可以直接根据目标对象生成子c,但这U方式ƈ不推荐?br />我们q像以前一L试我们的GreetingpȝQ测试代码和代码片段8是一L。运行结果如下:
Speaker called!
Hello!
看到效果了吧Q而且你可以发玎ͼ我们加入Log功能q没有改变以前的代码Q甚x试代码都没有改变Q这是AOP的魅力所在!我们更改的只是配|文件?br />下面解释一下刚才落下的MethodBeforeAdvice。关于这个类我ƈ不详l介l,因ؓq涉及到Spring中的另外一个概念“连接点QJointpointQ”,我详l介l一个beforeq个Ҏ。这个方法有三个参数arg0表示目标对象在哪个点被切入了Q既然是MethodBeforeAdviceQ那当然是在Method之前被切入了。那么arg0是表示的那个Method。第二个参数arg1是Method的参敎ͼ所以类型是Object[]。第三个参数是目标对象了,在Greeting例子中arg2的类型实际上是Speaker?br />在Greeting例子中,我们q没有指定目标对象的哪些Ҏ要被切入Q而是默认切入所有方法调用(虽然Speaker只有一个方法)。通过自定义PointcutQ可以控制切入点Q我q里不再介绍了,因ؓqƈ不媄响理解Spring AOPQ有兴趣的话去google一下就知道了?/font>

六、实战Spring
虽然q部分取名ؓ“实战Spring”,但实际上我ƈ不打在q里介绍实际开发Spring的内容,因ؓ我写q篇文章的目的是介绍Spring的概念和用Spring开发的思\Q而不是有关Spring的实践和详细介绍。文中介l的内容和用Spring做实际开发还相去甚远。之所以取名“实战Spring”是我觉得理解了上文讲的内容以后Q可以开始ؓ深入学习Spring和学习如何在目中应用Spring了?br />要系l的学习Springq是需要阅M本详l介lSpring的书Q我推荐Spring in ActionQ因为我看的是q本书。希望这文章能Zpȝ的学习Spring扫除一些障?/font>



]]>
վ֩ģ壺 ɽ| | ˹| | | | ¹| | | | | ղ| տ| | | | | | | | Դ| ÷ӿ| Ȫ| ͨ| ų| | | ƽ| ͤ| | | | | | | | | | ϳ| ٽ| ͺ|