Spring的影响实在太大了,连Python也在向其靠拢了。
一直以为Spring只是跟Java非常亲密,原来Spring早就潜入Python了。今天本来只是想Spring如何应用在Python中,于是就Google了下,发现原来Python早已经有个叫SpringPython东东了。于是到其官网下载了springpython-reference.pdf,粗略的翻翻学习了下。感觉其实跟Spring Java非常的相似,只是类名等不同而已。其IoC、AOP、数据访问、事务等都差不多了。
于是我边看文档,边整理了一下。因为现在我还没有Python项目,用不上它,所以现在只是做个笔记,知道个大概,为以后应用它时能够快速定位做个准备。
AOP那一章节没有写,因为一是跟Spring非常的像,二是项目中一般都很少用它。
一、IoC容器
1、ObjectContainer和ApplicationContainer比较
ApplicationContainer继承ObjectContainer对象,和Spring Java一样,它同样是增强了功能,提供了Bean的pre-和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销毁时,都会执行该方法。我们可以把销毁实例、释放内存等工作放在该方法之中。
需要注意的是,当同时定义了destroy和destroy_method两个方法时,ApplicationContext会优先执行destroy方法;继承自DisposableObject的对象必须提供destroy或是destroy_method方法,否则会报错,错误日志会被记录在SpringPython日志文件中。
2、对象生命周期
SpringPython提供了对象的两种生命周期:SINGLETON和PROTOTYPE。
默认情况下为SINGLETON,当类实例化时,容器会注入对象所有属性。
使用方法和Spring Java一样:scope=“prototype”。
3、SpringPython的配置
目前常见的配置有两种:XMLConfig和YamlConfig。受到Spring JavaConfig的启发,通过扩展PythonConfig并且使用@Object装饰,我们可以用纯Python代码来配置Bean。同样的,我们可以通过扩展Config来定义自己的格式。
XMLConfig跟Spring 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)、集合(set、frozenset)、元组(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>
|
注意set和frozenset的关系和区别(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, bool和complex)在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提供了两种类型的工厂:ReflectiveObjectFactory和PythonObjectFactory。它们很少被我们用到,主要是用在不的同配置扫描器中。
5、在运行时查询或是修改ApplicationContent
ApplicationContext实例暴露了两个属性和一个方法使用我们在运行时能够知道其当前状态并且动态改变它:object_defs、objects、get_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,从而使它返回最终结果。
一种便利的RowMapper:SimpleRowMapper(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愉快!
分享到:
相关推荐
调用 Python 脚本的方法非常简单,只需要使用 SpringBoot 框架中的命令行工具来调用 Python 脚本。下面是一个简单的示例代码: 首先,需要创建一个 Python 文件,例如 `python_script.py`,并在其中编写需要执行的...
Spring框架不仅仅是一个简单的IoC容器,它还提供了大量中间层功能,如事务管理、数据访问对象(DAO)支持、AOP(面向切面编程)等。在事务管理方面,Spring提供了一种通用的事务策略,允许开发者在不同的持久化技术...
- 安装Python后会获得Python解释器、命令行交互环境和简单的集成开发环境。 - 在MacOS下,如果系统版本低于10.8需升级到10.9以获得Python 2.7。 - 在Linux下,假设用户具有系统管理经验,自行安装Python 2.7。 -...
在这份教程中,廖雪峰深入浅出地介绍了Python编程语言的基础知识,以及如何用它来实现各种功能。 首先,教程介绍了什么是编程语言,它指出编程语言是为了让计算机执行任务而创建的高级指令集,最终必须被翻译成...
通过以上总结,可以看出廖雪峰的Python教程不仅提供了Python语言的基本介绍,还详细阐述了Python语言的特点、应用场景以及学习建议。该教程非常适合编程初学者,通过循序渐进的方式帮助他们掌握Python编程的基础知识...
根据提供的文件信息,廖雪峰的Python 3教程主要介绍了Python语言的基础知识和特点,并对教程的目标用户和作者背景进行了说明。以下知识点的详细说明: 1. Python语言特点 Python是一种高级计算机编程语言,它具备...
教程覆盖了Python的基础知识,并介绍了如何使用Python进行编程。对于那些有志于成为专业软件架构师的学习者来说,这是一个很好的起点。 廖雪峰的教程强调了学习Python的几个条件,包括:必须会使用电脑、应记住初中...
Python语言被誉为"优雅"、"明确"、"简单"。 2. 编程语言基础知识: 编程语言的最终目的是让计算机执行任务,例如下载文件、编辑文档等。不同编程语言在编写相同功能时代码量差异很大,Python因为是高级语言,所以在...
Turnquist,资深软件工程师,同时也是Spring Python 1.1的作者。他在开源社区活跃多年,为多个项目贡献过补丁,包括MythTV、Spring Security、MediaWiki和TestNG Eclipse插件等。他坚信敏捷开发实践和自动化测试的...
服务介绍: 1) 服务的注册与发现 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式...
该教程基于最新的Python 3版本,不仅介绍了Python的基础知识,还涉及到了实际编程示例,使得初学者可以在实践中逐步掌握Python编程。 廖雪峰作为本教程的作者,具有丰富的软件开发和开源项目经验。他精通Java、...
例如,Java的Spring框架、Python的Django框架以及Ruby on Rails都是流行的后端开发框架。这些框架提供了丰富的模块和工具,使得开发人员可以更加专注于业务逻辑的实现而不是重复编写基础代码。 后端开发的另一个...
通过以上的介绍,我们对Spring Cloud中的Nacos有了全面的认识。无论是服务发现还是配置管理,Nacos都为微服务架构带来了便利和高效。在实际项目中,根据具体需求选择合适的Nacos功能,可以有效提升系统的可扩展性和...
PYTHON的Django、Flask等Web框架的介绍和使用。 7. **数据库操作**:如何使用JAVA的JDBC和PYTHON的SQLite、MySQL等数据库操作库进行数据库交互。 8. **测试与调试**:单元测试、集成测试的概念和工具,如JUnit...
在这篇教程中,作者分享了如何使用Python的NetworkX库来绘制精美的网络图。NetworkX是一个用于创建、操作复杂网络结构的Python语言包,适用于研究人员、开发人员和对复杂网络感兴趣的用户。该库提供了很多功能强大的...
【NYU-Intro-to-Python-Spring-2018】是纽约大学2018春季学期开设的一门Python入门课程的教学资源集合。这门课程旨在为初学者提供Python编程的基础知识,帮助他们掌握这个广泛使用的编程语言。课程可能涵盖语法、...
在对日软件外包面试中,自我介绍是展现个人能力和专业...最后,记得在自我介绍结束时礼貌地表达感谢,例如:“以上就是我的简单介绍,非常感谢您给我这个机会。”这样既展示了你的专业素养,也给面试画上了圆满的句号。
- **Spring Boot**:简化了Java应用的开发过程,提供了一种快速构建独立、生产级别的基于Spring的应用的方式。 - **Django**:Python领域最流行的Web框架之一,以其“内聚力”和“懒惰”的开发哲学著称。 - **Flask*...
“工具”标签可能暗示了文章会介绍一些辅助开发规则引擎的工具,比如规则编辑器(如Drools Workbench)、规则测试工具,或者是集成规则引擎的框架,如Spring集成Drools等。这些工具能够简化规则的编写、测试和部署...