`
obullxl
  • 浏览: 182150 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SpringPython使用简单介绍

阅读更多

       Spring的影响实在太大了,连Python也在向其靠拢了。

一直以为Spring只是跟Java非常亲密,原来Spring早就潜入Python了。今天本来只是想Spring如何应用在Python中,于是就Google了下,发现原来Python早已经有个叫SpringPython东东了。于是到其官网下载了springpython-reference.pdf,粗略的翻翻学习了下。感觉其实跟Spring Java非常的相似,只是类名等不同而已。其IoCAOP、数据访问、事务等都差不多了。

于是我边看文档,边整理了一下。因为现在我还没有Python项目,用不上它,所以现在只是做个笔记,知道个大概,为以后应用它时能够快速定位做个准备。

AOP那一章节没有写,因为一是跟Spring非常的像,二是项目中一般都很少用它。

 

一、IoC容器

1ObjectContainerApplicationContainer比较

       ApplicationContainer继承ObjectContainer对象,和Spring Java一样,它同样是增强了功能,提供了Beanpre-post-创建逻辑。

       任何实现了ApplicationContextAware的对象将会有额外的app_context属性,它代表了ApplicationContext对象的一个引用。

from springpython.context import ApplicationContext

from springpython.config import XMLConfig

 

container = ApplicationContext(XMLConfig("app-context.xml"))

service = container.get_object("MovieLister")

 

继承ObjectPostProcessor对象并且定义了post_process_after_initialization方法的任何对象,在它实例创建之后 ApplicationContext都会执行该方法。

       继承springpython.context.DisposableObject对象并且定义了destroy或是destroy_method方法的对象,在ApplicationContext销毁时,都会执行该方法。我们可以把销毁实例、释放内存等工作放在该方法之中。

需要注意的是,当同时定义了destroydestroy_method两个方法时,ApplicationContext会优先执行destroy方法;继承自DisposableObject的对象必须提供destroy或是destroy_method方法,否则会报错,错误日志会被记录在SpringPython日志文件中。

 

2、对象生命周期

       SpringPython提供了对象的两种生命周期:SINGLETONPROTOTYPE

默认情况下为SINGLETON,当类实例化时,容器会注入对象所有属性。

       使用方法和Spring Java一样:scope=prototype”。

 

3SpringPython的配置

       目前常见的配置有两种:XMLConfigYamlConfig。受到Spring JavaConfig的启发,通过扩展PythonConfig并且使用@Object装饰,我们可以用纯Python代码来配置Bean。同样的,我们可以通过扩展Config来定义自己的格式。

       XMLConfigSpring Java 2.5 XSD非常相似,下面是一个简单的例子。

<?xml version="1.0" encoding="UTF-8"?>

<objects xmlns="http://www.springframework.org/springpython/schema/objects/1.1"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/springpython/schema/objects/1.1

http://springpython.webfactional.com/schema/context/spring-python-context-1.1.xsd">

<object id="MovieLister" class="springpythontest.support.testSupportClasses.MovieLister" scope="prototype">

<property name="finder" ref="MovieFinder"/>

<property name="description"><ref object="SingletonString"/></property>

</object>

<object id="MovieFinder" class="springpythontest.support.testSupportClasses.ColonMovieFinder" scope="singleton">

<property name="filename"><value>support/movies1.txt</value></property>

</object>

<object id="SingletonString" class="springpythontest.support.testSupportClasses.StringHolder" lazy-init="<property name="str" value="There should only be one copy of this string"></property>

</object>

</objects>

 

       内部对象:

<object id="MovieLister3" class="springpythontest.support.testSupportClasses.MovieLister">

<property name="finder">

<object id="named" class="springpythontest.support.testSupportClasses.ColonMovieFinder">

<property name="filename"><value>support/movies1.txt</value></property>

</object>

</property>

<property name="description"><ref object="SingletonString"/></property>

</object>

 

       SpringPython支持多种集合属性:字典(dict)、列表(list)、属性(props)、集合(setfrozenset)、元组(tuple);

<object id="ValueHolder" class="springpythontest.support.testSupportClasses.ValueHolder">

<constructor-arg><ref object="SingletonString"/></constructor-arg>

<property name="some_dict">

<dict>

<entry><key><value>Hello</value></key><value>World</value></entry>

<entry><key><value>Spring</value></key><value>Python</value></entry>

<entry><key><value>holder</value></key><ref object="SingletonString"/></entry>

<entry><key><value>another copy</value></key><ref object="SingletonString"/></entry>

</dict>

</property>

<property name="some_list">

<list>

<value>Hello, world!</value>

<ref object="SingletonString"/>

<value>Spring Python</value>

</list>

</property>

<property name="some_props">

<props>

<prop key="administrator">administrator@example.org</prop>

<prop key="support">support@example.org</prop>

<prop key="development">development@example.org</prop>

</props>

</property>

<property name="some_set">

<set>

<value>Hello, world!</value>

<ref object="SingletonString"/>

<value>Spring Python</value>

</set>

</property>

<property name="some_frozen_set">

<frozenset>

<value>Hello, world!</value>

<ref object="SingletonString"/>

<value>Spring Python</value>

</frozenset>

</property>

<property name="some_tuple">

<tuple>

<value>Hello, world!</value>

<ref object="SingletonString"/>

<value>Spring Python</value>

</tuple>

</property>

</object>

 

       注意setfrozenset的关系和区别(http://docs.python.org/release/2.5.2/lib/types-set.html):

 

       构造函数配置方法:

<object id="AnotherSingletonString" class="springpythontest.support.testSupportClasses.StringHolder">

<constructor-arg value="attributed value"/>

</object>

 

<object id="MultiValueHolder" class="springpythontest.support.testSupportClasses.MultiValueHolder">

<constructor-arg name="a"><value>alt a</value></constructor-arg>

<constructor-arg name="b"><value>alt b</value></constructor-arg>

</object>

 

       Python的基本类型(str, unicode, int, long, float, decimal.Decimal, boolcomplex)在XML配置文件中有着不同的简短的表示方法:

<str id="MyString">My string</str>

<unicode id="MyUnicode">Za#ó## g##l# ja##</unicode>

<int id="MyInt">10</int>

<long id="MyLong">100000000000000000000000</long>

<float id="MyFloat">3.14</float>

<decimal id="MyDecimal">12.34</decimal>

<bool id="MyBool">False</bool>

<complex id="MyComplex">10+0j</complex>

 

       同样的,XMLConfig也可以定义抽象(abstract="True")和使用继承(parent):

<object id="crm_service" parent="service" abstract="True">

<property name="port"><value>3393</value></property>

</object>

<object id="get_customer_id" parent="crm_service">

<property name="path"><value>/soap/invoke/get_customer_id</value></property>

</object>

 

       当在程序中需要引用一个抽象类型的对象时,必须加上属性(ignore_abstract=True),否则会引发AbstractObjectException异常:

service = ctx.get_object("service", ignore_abstract=True)

 

4、对象工厂

       SpringPython提供了两种类型的工厂:ReflectiveObjectFactoryPythonObjectFactory。它们很少被我们用到,主要是用在不的同配置扫描器中。

 

5、在运行时查询或是修改ApplicationContent

     ApplicationContext实例暴露了两个属性和一个方法使用我们在运行时能够知道其当前状态并且动态改变它:object_defsobjectsget_objects_by_type(type, include_type=True)

 

 

二、AOP编程

 

 

三、数据访问

1、数据库模板:

       在没有使用数据库模板情况下,我们传统的写法如下:

conn = MySQL.connection(username="me", password"secret", hostname="localhost", db="springpython")

cursor = conn.cursor()

results = []

try:

cursor.execute("select title, air_date, episode_number, writer from tv_shows where name = %s", ("Monty Python",))

for row in cursor.fetchall():

tvShow = TvShow(title=row[0], airDate=row[1], episodeNumber=row[2], writer=row[3])

results.append(tvShow)

finally:

try:

cursor.close()

except Exception:

pass

conn.close()

return results

       在传统的数据库访问中,所有的数据库操作都是建立连接、执行查询、获取数据、释放连接,最后是返回结果。

       下面是在使用了数据库模板情况下的做法:


 

""" The following part only has to be done once."""

from springpython.database.core import *

from springpython.database.factory import *

connectionFactory = MySQLConnectionFactory(username="me", password="secret", hostname="localhost", db="springpython")

dt = DatabaseTemplate(connectionFactory)

 

class TvShowMapper(RowMapper):

"""This will handle one row of database. It can be reused for many queries if they

are returning the same columns."""

def map_row(self, row, metadata=None):

return TvShow(title=row[0], airDate=row[1], episodeNumber=row[2], writer=row[3])

 

results = dt.query("select title, air_date, episode_number, writer from tv_shows where name = %s", \

("Monty Python",), TvShowMapper())
results = dt.query("select title, air_date, episode_number, writer from tv_shows where episode_number < %s", \

(100,), TvShowMapper())

results = dt.query("select title, air_date, episode_number, writer from tv_shows where upper(title) like %s", \

("%CHEESE%",), TvShowMapper())

results = dt.query("select title, air_date, episode_number, writer from tv_shows where writer in ('Cleese', 'Graham')",

rowhandler=TvShowMapper())

       从上面可以看出,在使用了模板后,程序所要做的,就是提供一个RowMapper,从而使它返回最终结果。

       一种便利的RowMapperSimpleRowMapper(TvShow)。它自动把数据表列和对象属性关联起来。

2、把数据行映射成字典

results = dt.query("select title, air_date, episode_number, writer from tv_shows where episode_number < %s", \

(100,), DictionaryRowMapper())

 

 

四、事务管理

1、事务模板TransactionTemplate

class Bank:

def __init__(self):

self.factory = factory.MySQLConnectionFactory("springpython", "springpython", "localhost", "springpython")

self.dt = DatabaseTemplate(self.factory)

self.txManager = ConnectionFactoryTransactionManager(self.factory)

self.txTemplate = TransactionTemplate(self.txManager)

 

try:

self.txTemplate.execute(txDefinition())

print "If you made it to here, then your transaction has already been committed."

except InvalidBankAccount, InsufficientFunds:

print "If you made it to here, then your transaction has already been rolled back."

 

2、使用装饰@transactional

@transactional

def transfer(self, transfer_amount, source_account_num, target_account_num):

self.withdraw(transfer_amount, source_account_num)

self.deposit(transfer_amount, target_account_num)

 

3、事务传播属性

       当使用@transactional装饰时,同时也可以指定事务传播属性,比如:@transactional(["PROPAGATION_REQUIRED"])

       事务一共有4种传播属性:

       PROPAGATION_SUPPORTS:程序能够在有事务或是没有事务的环境中运行,也就是有没有无所谓;

PROPAGATION_REQUIRED:如果当前没事务,则开始一个事务;

PROPAGATION_MANDATORY:程序逻辑只能在事务中运行,如果没有,则产生异常;

PROPAGATION_NEVER:与上面的相反,程序只能在无事务的环境中运行,如果有事务,则产生异常。

 

 ===========================================
如有批评、指教、疑惑,请:obullxl@163.com
祝大家使用JAVA愉快!

分享到:
评论
23 楼 amu_lucifer 2011-01-19  
spring其实之前也关注过,可以xml配置文件大家都觉得繁琐。而python要的就是大道至简。

LZ的文章末尾。。用的是 “祝大家使用JAVA愉快”。。。。。。

编程思想可以通用,但是,模式还是不要随便套用。

至于事务,django支持的不错,或者SQLAlchemy也不错。

总得来说,技术是来探讨。也别求全责备。LZ对技术的关注很值得佩服。

咱是菜鸟,只做了1年半java2年python。。说说自己的意见。。然后飘过。。。
22 楼 JeffreyHsu 2010-11-25  
作为一个资深java和python开发者,我表示springpython就是一个大杯具
不解释

python圈子根本不买账的
21 楼 mmdebbs 2010-11-22  
可以学习一下啊
20 楼 wooodyhuang 2010-11-18  
我绝对不会去尝试这样做~~~
19 楼 mathgl 2010-11-17  
<div class="quote_title">汪兆铭 写道</div>
<div class="quote_div">
<div class="quote_title">obullxl 写道</div>
<div class="quote_div">
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span lang="EN-US"><span>       </span>Spring</span><span>的影响实在太大了,连</span><span lang="EN-US">Python</span><span>也在向其靠拢了。</span></span></p>
</div>
<p>是python向spring靠拢吗,别搞笑了。分明是spring拿脸往python冷屁股上贴</p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
</div>
<p> </p>
<p>python本身就可以作为一门配置语言使用。。例如我现在做的,用ironpython作为配置来 加载模块,调用接口。。</p>
<p> </p>
<p>一个图灵机完备的语言在灵活程度远远超过 xml。在python上 又加入xml作为配置 未必多此一举</p>
18 楼 汪兆铭 2010-11-17  
<div class="quote_title">obullxl 写道</div>
<div class="quote_div">
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span lang="EN-US"><span>       </span>Spring</span><span>的影响实在太大了,连</span><span lang="EN-US">Python</span><span>也在向其靠拢了。</span></span></p>
</div>
<p>是python向spring靠拢吗,别搞笑了。分明是spring拿脸往python冷屁股上贴</p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
17 楼 liangguanhui 2010-11-10  
rootsoso 写道
obullxl 写道
attol 写道
obullxl 写道
超级潜水员 写道
不是spring影响太大,是这帮人太二,而且完成照搬spring的东西至python那就更二.

楼主认同spring这种方式,应该是刚学习python,才会对这垃圾东西关注

唉,悲剧~~这样的抱怨批评跟没说一样,没有任何见解!



要见解是吧? 见解就是"要自己思考,不要盲目崇拜"

你硬要用JAVA那套来往Python身上套,这不是个悲剧么,看上面列的那一大堆config,头就大

你非要把飞机的机翼放到汽车上,还说,"嗯.这样会让这个车看起来更像飞机"..

很纳闷,1、什么地方体现出所谓的盲目崇拜?2、什么地方体现了所谓的汽车看起来像飞机?人生就是一个悲剧!


我想起来了经典的: 太阳能手电筒

Spring这种东西只适合Java这类静态语言,跟Python这类动态语言基本是“太阳能手电筒”
16 楼 rootsoso 2010-11-09  
obullxl 写道
attol 写道
obullxl 写道
超级潜水员 写道
不是spring影响太大,是这帮人太二,而且完成照搬spring的东西至python那就更二.

楼主认同spring这种方式,应该是刚学习python,才会对这垃圾东西关注

唉,悲剧~~这样的抱怨批评跟没说一样,没有任何见解!



要见解是吧? 见解就是"要自己思考,不要盲目崇拜"

你硬要用JAVA那套来往Python身上套,这不是个悲剧么,看上面列的那一大堆config,头就大

你非要把飞机的机翼放到汽车上,还说,"嗯.这样会让这个车看起来更像飞机"..

很纳闷,1、什么地方体现出所谓的盲目崇拜?2、什么地方体现了所谓的汽车看起来像飞机?人生就是一个悲剧!


我想起来了经典的: 太阳能手电筒
15 楼 thinkx 2010-11-08  
spring在java上是不错的,不过这东西和python简洁的理念是相悖的。
我觉得,在python上搞这个就是有病
14 楼 hardPass 2010-11-08  
ao ,搞错了,以为是Jython的呢
13 楼 油炸大龙虾 2010-11-05  
py没有spring的时候,能活的好好的。
12 楼 joy2everyone 2010-11-05  
  Spring的影响实在太大了,连Python也在向其靠拢了。

个人觉得不是python在向Spring靠近,恰恰相反,Python做为一门动态语言,需要spring AOP,Ioc的那种方式编程吗?
11 楼 snow8261 2010-11-04  
研究,学习,学习。
10 楼 jeffreydan 2010-11-04  
太悲剧了···一个追求轻量级的开发语言硬是被套上个笨重的框架···太累··太累鸟··
9 楼 obullxl 2010-11-04  
attol 写道
obullxl 写道
超级潜水员 写道
不是spring影响太大,是这帮人太二,而且完成照搬spring的东西至python那就更二.

楼主认同spring这种方式,应该是刚学习python,才会对这垃圾东西关注

唉,悲剧~~这样的抱怨批评跟没说一样,没有任何见解!



要见解是吧? 见解就是"要自己思考,不要盲目崇拜"

你硬要用JAVA那套来往Python身上套,这不是个悲剧么,看上面列的那一大堆config,头就大

你非要把飞机的机翼放到汽车上,还说,"嗯.这样会让这个车看起来更像飞机"..

很纳闷,1、什么地方体现出所谓的盲目崇拜?2、什么地方体现了所谓的汽车看起来像飞机?人生就是一个悲剧!
8 楼 attol 2010-11-03  
obullxl 写道
超级潜水员 写道
不是spring影响太大,是这帮人太二,而且完成照搬spring的东西至python那就更二.

楼主认同spring这种方式,应该是刚学习python,才会对这垃圾东西关注

唉,悲剧~~这样的抱怨批评跟没说一样,没有任何见解!



要见解是吧? 见解就是"要自己思考,不要盲目崇拜"

你硬要用JAVA那套来往Python身上套,这不是个悲剧么,看上面列的那一大堆config,头就大

你非要把飞机的机翼放到汽车上,还说,"嗯.这样会让这个车看起来更像飞机"..
7 楼 whitesock 2010-11-03  
People fear what they don't know
6 楼 obullxl 2010-11-03  
超级潜水员 写道
不是spring影响太大,是这帮人太二,而且完成照搬spring的东西至python那就更二.

楼主认同spring这种方式,应该是刚学习python,才会对这垃圾东西关注

唉,悲剧~~这样的抱怨批评跟没说一样,没有任何见解!
5 楼 mathgl 2010-11-03  
python要spring作甚?

感觉有些 ruby用spring的感觉....
4 楼 差沙 2010-11-03  
如楼上所说,简直就是悲剧。

相关推荐

Global site tag (gtag.js) - Google Analytics