[转载] 一篇不错的Spring Framework的tutorial

[作者] Benoy Jose
[地址] http://javaboutique.internet.com/tutorials/spring_frame/article.html
[点评] 介绍的比较全面,但也稍嫌单薄,是Rod Johnson在邮件列表中给的连接,说明还不错。

[原文]

Introduction

Officially the spring season might be over but spring still seems to be lingering around. If you did not get the smell of the Spring Framework this summer then you might be missing something. You might be having your fingers crossed skeptically about another run of the mill Framework system that we have been seeing for the last couple of years. Hundreds of open source and propriety frameworks have sprung all over the place making it difficult to identify what each framework does, so the skepticism is understandable, but before we write off spring like one of those others it might be worth briefly peeking through it. Spring proposes a new paradigm, a pluggable, non- intrusive and robust framework.

Summary

Unlike other frameworks and APIs, spring does not impose itself wholly on to the design of a project. Spring is modular and has been divided logically into independent packages, which can function independently. The architects of an application have the flexibility to implement just a few spring packages and leave out most of the packages in spring. The "Spring Framework" would not feel bad with this attitude and on the contrary encourages users to introduce Spring into existing applications in a phased manner. So no matter what kind of framework you are using now Spring will co-exist with it without causing you nightmares and further more Spring will allow you to choose specific packages in Spring.

The "Struts" framework is no doubt a good framework to enhance the ability of the web tier, but the biggest drawback is the fact that it caters only to the web tier and leaves most of the Enterprise tier or middle tier to the fancy of the application architects. The Application architects need to provide an additional framework to deal with the enterprise tier and make sure that the new framework integrates well with the Struts framework. Spring tries to alleviate this problem by providing a comprehensive framework, which includes an MVC framework, an AOP integration framework, a JDBC integration framework, and an EJB integration framework. It also provides integration modules for major O/R mapping tools like Hibernate and JDO. Spring provides all these in a modular fashion without imposing any layer on to the user. Spring is not a take-it-or- leave-it kind of framework. It tries to seamlessly blend into the existing framework users have without hindrances. Spring also provides transaction management support using Java classes, email support packages using framework classes, web services support through proxies and many more features like the above. As mentioned earlier all these packages are optional and spring does not make any of them mandatory. Spring can seamlessly integrate with existing applications and provide specific functionality that you intend to provide with minimal demands for customization. A user can continue to use Struts for the web tier and toplink O/R for the database and meanwhile hook spring to provide e-mail services and web services support. Spring is based on the Inversion of Control/Dependency Injection pattern that has been making rounds in message boards all over the Internet.

Inversion of Control/Dependency Injection

Dependency injection is kind of an Inversion of Control pattern. It is proposed as an alternative for the Service Locator. Martin flower discusses the Dependency Injection pattern, Inversion of Control pattern and the differences it has with the service locator in an article at his site (See resources below).

Dependency Injection proposes separating the implementation of an object and the construction of objects that depend on them. The job of coordinating the implementation and construction is left to the Assembler code. The object that needs to be implemented does not need to instantiate the dependent objects and can rely on the assembler to do the job. The assembler will gather and instantiate, if necessary, all the dependent objects and make them available to the implemented object. Since the assembler does not depend on the code directly changes can be made to the assembler without any changes to the code. The assembler gathers the required classes through configuration files so a change in the assembler only needs changes to the configuration file. In this case the Assembler code would be the spring framework.

Since the classes are independent and are integrated through the assembler, independent testing of each class can be done without affecting other application codes.

There are three types of Dependency Injections.

  • Type 1 IOC also called Interface Injection In Type 1 IOC the injection is done though an interface. The interface will define the injection method and the implementation class has to implement this interface and provide concrete implementation for the injection method.
  • Type 2 IOC also called Setter Injection In Type 2 IOC the injection is done via a setter method. Type 2 IOC uses setter methods to get the dependent classes it needs.
  • Type 3 IOC also called Constructor Injection. In Type 3 IOC implementing class defines a constructor to get all its dependents. The dependent classes are defined in the constructor arguments.

    How does Spring Work?

    The idea is that beans follow the Dependency Injection pattern. Beans have information on the classes dependent on them. Beans define their own attributes within bean descriptors and also define the beans they depend on in the same descriptors. The Bean does not need to locate and instantiate these classes using service locators or JNDI calls. The Assembler (Spring Framework in this case) takes care of finding these classes based on the information provided in the descriptor and makes them available to the calling class. The service locator pattern does almost the same job, so why do we need another pattern to do it. The class that needs the dependent classes needs to tell the Service Locator as to which classes are required by it and moreover the responsibility of finding these classes and invoking them falls on the calling class. This makes the classes tightly coupled with each other making them difficult to unit test them separately. In the case of the Dependency Injection pattern the responsibility is shifted to the Assembler to load these classes. The assembler can make changes to the dependent classes by simply modifying the descriptor file. Martin Flower’s article in the resources shows the comparison between Dependency Injection and Service Locator with a good example.

    Beans, BeanFactory and Application Context

    The basic package in the spring framework is the org.springframework.beans package. Spring framework uses JavaBeans and this package provides most of the basic functionality to manipulate Java beans and provides the basic infrastructure for the other spring framework classes. This package also provides the basis for the "Dependency injection" pattern that Spring is based on.

    There are two ways in which clients can use the functionality of the Spring Framework--the BeanFactory and the ApplicationContext. The BeanFactory is a generic factory, which stores the information about all the Spring Beans and allows the user to instantiate beans and manage them. The BeanFactory provides programmers with the facilities to implement the basic features of the Spring Framework. The ApplicationContext builds on top of the BeanFactory and inherits all the basic features of the Spring Framework. Apart from the basic features, ApplicationContext provides additional features like Event management, internationalization support and resource management.

    The BeanFactory is particularly useful in low memory situations like in an Applet where having the whole API would be overkill. It provides the basic spring framework features and does not bring all the excess baggage that ApplicationContext has. ApplicationContext helps the user to use Spring in a framework oriented way while the BeanFactory offers a programmatic approach.

     

    BeanFactory

    A BeanFactory is like a factory class that contains a collection of beans. The BeanFactory holds BeanDefinitions of multiple beans within itself and then instantiates the bean whenever asked for by clients.

    XMLBeanFactory is a BeanFactory implementation provided within the Spring Framework. The XMLBeanFactory can read BeanDefinitions from a XML file directly. The XMLBeanFactory validates the XML using a DTD file called beans.dtd and checks for inconsistencies in the XML.

    Bean Class

    The Bean, which is stored in the BeanFactory, is the actual class that would carry the logic for the bean. Spring does not define any standards on how the bean needs to be structured. Any J2EE complaint bean structure is acceptable to Spring. Unlike Struts and other frameworks the beans do not need to implement any special Spring interfaces to make them work in the Spring Framework. Depending upon the kind of Inversion required the bean might have to follow the rules of the corresponding Inversion Dependency pattern. Spring supports only Constructor based injection and setter based injection. So a bean that used constructor-based injection should have to define constructors accordingly. Spring recommends setter-based injection over constructor-based injection as multiple constructors can make the bean huge and unmanageable.

    A bean has one or more IDs associated with it. The ID should be unique within the BeanFactory it is contained in so that the BeanFactory can look up the bean using the ID. If a bean has multiple IDs they are defined as aliases for the bean.

    The spring framework takes care of how the beans can be created and sent back to clients. Beans can be deployed as singletons or as non-singletons. If a bean is defined as a singleton then only one instance of the bean is created by the BeanFactory and returned when a request for the bean is made. All subsequent requests get the same instance which was created first. Non- singleton beans or Prototype beans can have multiple instances created. So each time a request is made for a bean to the BeanFactory a new instance is created and returned. The BeanFactory cannot do Lifecycle management of a prototype bean, as a new instance is created for each client who requests it(Lifecycle management of a bean is discussed in a subsequent section).

    BeanDefinition

    The BeanDefinition contains all the information required by the BeanFactory to instantiate the bean. This includes any dependencies the bean may have on other beans and how the bean needs to be configured in the container. When a request is made for a bean, the BeanFactory loads the corresponding BeanDefinition and instantiates the bean. The BeanDefinition has information on how the bean would be instantiated (Singleton or prototype) and callback methods defined in the Lifecycle section.

    Lifecycle of a Bean

    After the bean is initialized the BeanFactory can use callback methods to change the behavior of the bean in the BeanFactory. One of the callback methods is the init-method. The InitializingBean interface of the factory package gives the ability to do initialization work after properties are set up for a bean in the BeanFactory. The afterPropertiesSet () method in the InitializingBean interface allows the user to check if all the properties are set properly or if some operation has to be done after the properties have been set. All Bean classes that need to use this callback method need to implement the InitializingBean interface and implement the afterPropertiesSet () method. If the initialization work is minimal the user has the flexibility to designate a method within the bean, which will be invoked after bean properties have been set. The designated method, which would do the initialization, can be then be specified in the init-method attribute of the bean. Designating the init-method attribute can help to avoid implementing the InitializingBean interface.

    In a similar fashion a DisposableBean interface is provided to do cleanup operations after a bean is destroyed. The bean has a destroy-method attribute that can used to designate a method within the bean, which will do the clean up work when the BeanFactory destroys the bean.

    Other Features:

  • Spring can automatically resolve the dependent beans with the help of the BeanFactory. This facility can reduce the need to specify properties or constructor arguments.
  • Spring can check dependencies on a bean. It can check for values that should be set when a bean is initialized. If the check is not done the BeanFactory will set the default value. This behavior is not mandatory and can be turned on when required.
  • Spring can also manage multiple resource files for you.

    Sample

    Lets go through a sample to illustrate a few of the important ideas outlined above. Shown below is a snippet of XML that defines some BeanDefinitions of an actual bean.

    <bean id = ‘helloWorldSample′ 
    class=”com.helloworld.samples.HelloWorld”
    depends-on = ”boostrapClassId”>
    <property name=”myString”>
    My famous Hello World Program</property>
    <property name=”dependentClassId”>
    <ref bean = “firstDependentClass”/>
    </property>
    </bean>

    <bean id = “firstDependentClass”
    class = “com.helloworld.dependent.FirstDependentClass”
    destroy-method=”cleanupMethod”>
    <property name=”dependentString”>
    My famous Hello World Program needs me</property>
    <bean>

    <bean id = “bootstrapClassId”
    class = “com.helloworld.config.BootStrapClass”
    init-method = “loadPropertiesFromFile”>

    The sample above shows a BeanDefinition for a HelloWorld Class, which depends upon the BootStrapClass class. The property ‘myString’ would translate into a field into the bean with a default value specified within it. Since the BeanFactory knows that this bean requires the class FirstDependentClass, it would instantiate that class before it sets the reference for that class in the main bean. The property "dependentClassId" would also become a field in the bean with a reference to the FirstDependentClass. The loadProertiesFromFile method which is specified as a init method will be invoked after properties have been set to the BootStrapClass bean.

    Application Context

    The ApplicationContext provides a framework type of API to Spring. The framework allows the user to use a ContextLoader to load beans. The ContextLoader does the job of the BeanFactory. The ApplicationContext provides all the features offered by BeanFactory and allows the user to add some additional features. Some of the features offered by the ApplicationContext are MessageSources, Resource management and Event Propagation.

    MessageSource offers an i18n type messaging facility. Event Propagation allows Spring to have an event handling mechanism. The Event handling is done via the ApplicationEvent Class and the ApplicationListener interface. Every bean that’s wants to be notified of any events would implement the ApplicationListener Interface. Whenever an ApplicationEvent takes place the ApplicationContext knows about it. The ApplicationContext would notify the beans that are listening to this event.

    Additional Support

    Spring provides a lot of additional modules, which are optional to the framework. The User has the flexibility to use them, as they need them in their application. Some of these features are briefly discussed below.

    Spring AOP

    Spring does not need Aspect Oriented Programming (AOP) to function as a framework. AOP enhances the Spring middleware support by providing declarative services. The declarative services can be used as replacements for the EJB declarative services used in CMTs. The EJB "declarative services" are provided by Spring using the "declarative transaction management service." Transaction management services are based on the spring transaction management, which will be discussed next.

    Transaction Management
    Spring provides a simple programmatic transaction management API. Spring provides support for both declarative transaction management and programmatic transaction management. Declarative transaction management is used in EJB container managed transactions (CMT) and programmatic transaction management is used in EJB bean managed persistence. Additionally Spring can use transaction management to avoid the use of EJBs where not required.
    Data Access using JDBC

    The org.springframework.jdbc package provides all the JDBC related support required by the application. One of the interesting interfaces within this package is the SQLExceptionTranslator. The translator can help in providing translations from the very common and generic SQLException in to something more specific and informative. SQLExceptions are too generic and cannot provide any great information that can be passed back to the user. Spring’s wrapper (SQLExceptionTranslator) can implemented specific to a vendor and can provide informative error messages, which can be sent back to the user.

    O/R Mapping
    Spring provides integration with OR mapping tools like Hibernate, JDO and iBATIS. (For information on Hibernate see resources below). Spring provides very good support for Hibernate. Spring augments the power of Hibernate by providing support for Hibernate sessions, Hibernate transaction management and other features in Hibernate.
    Spring Web Framework
    Spring provides a pluggable MVC architecture. The users have a choice to use the web framework or continue to use their existing web framework. Spring separates the roles of the controller; the model object, the dispatcher and the handler object which makes it easier to customize them. Spring web framework is view agnostic and does not push the user to use only JSPs for the view. The user has the flexibility to use JSPs, XSLT, velocity templates etc to provide the view.
    Spring And EJB
    In a usual EJB application EJBs are located using service locators and managed using business delegates. These results in EJB JNDI look ups scattered all over the code. Spring can provide proxy objects, which can act as business delegates do the same job. These proxies can be configured into the BeanFactory and the ApplicationContext.
    Conclusion
    Spring is very new to the market and provides a new lease of life to framework development. Spring does not try to duplicate existing solutions; it tries to integrate with exiting solutions like JDO, AOP and Hibernate. However spring creates a new web framework to replace Struts, as the creators of Spring feel that Struts is not robust enough. Spring would generate great interest in the coming months as more people become aware of it and find it worthwhile to implement. Spring is portable across application servers, as it does not include any application server or platform specific requirements. This makes it compatible on major application servers like Websphere, Weblogic, Tomcat, Jboss and others like them. As of now spring can be integrated and used in a eclipse IDE, however as the versions improve spring should be providing support for more IDEs.

    Benoy Jose is a web developer with over six years of experience in J2EE and Microsoft technologies. He is a Sun Certified programmer and enjoys writing technical and non-technical articles for various magazines.




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
标题:深入理解Java反射机制 摘要:Java反射机制是一种强大的特性,它允许在运行时动态地获取和操作类的信息。本文将深入探讨Java反射机制的原理、应用场景以及使用方法。 正文: 一、什么是Java反射机制? Java反射机制是指在运行时通过程序获取类的信息,并且可以动态调用类的方法、访问和修改类的属性,以及创建对象等操作。它使得我们可以在不知道类的具体信息的情况下,对类进行操作。 二、Java反射机制的原理 Java反射机制的核心类是Class类,它代表一个类或接口。通过Class类,我们可以获取类的构造方法、方法、属性等信息。Java反射机制主要涉及以下几个重要的类和接口: 1. Class类:代表一个类或接口,在运行时可以获取类的相关信息。 2. Constructor类:代表类的构造方法,可以用来创建对象。 3. Method类:代表类的方法,可以用来调用方法。 4. Field类:代表类的属性,可以用来访问和修改属性的值。 通过这些核心类和接口,我们可以在运行时动态地加载和使用类,而不需要在编译时确定类的具体信息。 三、Java反射机制的应用场景 Java反射机制在许多框架和工具中得到广泛应用,下面列举几个常见的应用场景: 1. 框架开发:许多框架,如SpringHibernate等,都使用了反射机制来实现动态创建对象、调用方法等功能。 2. 单元测试:JUnit等测试框架使用反射机制来执行被测试类的方法。 3. 配置文件解析:通过反射机制,可以根据配置文件中的类名动态加载和初始化对象。 4. 动态代理:反射机制可以实现动态代理,通过在运行时生成代理对象,来增强方法的功能。 四、Java反射机制的使用方法 Java反射机制提供了一系列的方法来操作类,包括获取类名、获取构造方法、调用方法、访问和修改属性等。下面是一些常用的反射方法: 1. 获取类名:使用Class类的getName()方法可以获取类的全限定名。 2. 获取构造方法:使用Class类的getConstructors()或getDeclaredConstructors()方法可以获取类的构造方法。 3. 调用方法:使用Method类的invoke()方法可以调用类的方法。 4. 访问和修改属性:使用Field类的get()和set()方法可以访问和修改类的属性。 需要注意的是,在使用反射机制时,要处理好异常情况,并且在性能要求较高的场景下,应谨慎使用反射,以避免性能开销过大的问题。 结论: Java反射机制是一种强大的特性,它允许在运行时动态地获取和操作类的信息。通过反射机制,我们可以实现诸如动态创建对象、调用方法、访问和修改属性等功能。尽管反射机制具有一定的性能开销,但在许多框架和工具中得到广泛应用。了解和掌握Java反射机制,将会为我们的开发工作带来更多的灵活性和便利性。 参考文献: - Oracle官方文档 - Java反射:https://docs.oracle.com/javase/tutorial/reflect/ - 廖雪峰的Java教程 - 反射:https://www.liaoxuefeng.com/wiki/1252599548343744/1264804593397984

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值